=== RUN   TestResetPasswordCommand_Succeeds
--- PASS: TestResetPasswordCommand_Succeeds (0.14s)
PASS
ok  	github.com/Wikid82/charon/backend/cmd/api	(cached)
=== RUN   TestSeedMain_Smoke
{"level":"info","msg":"✓ Database migrated successfully","time":"2025-12-12T19:01:35Z"}
{"level":"info","msg":"✓ Created remote server: Local Docker Registry (localhost:5000)","server":"Local Docker Registry","time":"2025-12-12T19:01:35Z"}
{"level":"info","msg":"✓ Created remote server: Development API Server (192.168.1.100:8080)","server":"Development API Server","time":"2025-12-12T19:01:35Z"}
{"level":"info","msg":"✓ Created remote server: Staging Web App (staging.internal:3000)","server":"Staging Web App","time":"2025-12-12T19:01:35Z"}
{"level":"info","msg":"✓ Created remote server: Database Admin (localhost:8081)","server":"Database Admin","time":"2025-12-12T19:01:35Z"}
{"host":"app.local.dev","level":"info","msg":"✓ Created proxy host: app.local.dev -\u003e http://localhost:3000","time":"2025-12-12T19:01:35Z"}
{"host":"api.local.dev","level":"info","msg":"✓ Created proxy host: api.local.dev -\u003e http://192.168.1.100:8080","time":"2025-12-12T19:01:35Z"}
{"host":"docker.local.dev","level":"info","msg":"✓ Created proxy host: docker.local.dev -\u003e http://localhost:5000","time":"2025-12-12T19:01:35Z"}
{"level":"info","msg":"✓ Created setting: app_name = Charon","setting":"app_name","time":"2025-12-12T19:01:35Z"}
{"level":"info","msg":"✓ Created setting: default_scheme = http","setting":"default_scheme","time":"2025-12-12T19:01:35Z"}
{"level":"info","msg":"✓ Created setting: enable_ssl_by_default = false","setting":"enable_ssl_by_default","time":"2025-12-12T19:01:35Z"}

2025/12/12 19:01:35 [31;1m/projects/Charon/backend/cmd/seed/main.go:218 [35;1mrecord not found
[0m[33m[0.135ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE email = "admin@localhost" ORDER BY `users`.`id` LIMIT 1
{"level":"info","msg":"✓ Created default user: admin@localhost","time":"2025-12-12T19:01:35Z","user":"admin@localhost"}
{"level":"info","msg":"\n✓ Database seeding completed successfully!","time":"2025-12-12T19:01:35Z"}
{"level":"info","msg":"  You can now start the application and see sample data.","time":"2025-12-12T19:01:35Z"}
--- PASS: TestSeedMain_Smoke (0.19s)
PASS
ok  	github.com/Wikid82/charon/backend/cmd/seed	(cached)
?   	github.com/Wikid82/charon/backend/integration	[no test files]
=== RUN   TestAccessListHandler_SetGeoIPService
--- PASS: TestAccessListHandler_SetGeoIPService (0.00s)
=== RUN   TestAccessListHandler_SetGeoIPService_Nil
--- PASS: TestAccessListHandler_SetGeoIPService_Nil (0.00s)
=== RUN   TestAccessListHandler_Get_InvalidID
--- PASS: TestAccessListHandler_Get_InvalidID (0.00s)
=== RUN   TestAccessListHandler_Update_InvalidID
--- PASS: TestAccessListHandler_Update_InvalidID (0.00s)
=== RUN   TestAccessListHandler_Update_InvalidJSON
--- PASS: TestAccessListHandler_Update_InvalidJSON (0.00s)
=== RUN   TestAccessListHandler_Delete_InvalidID
--- PASS: TestAccessListHandler_Delete_InvalidID (0.00s)
=== RUN   TestAccessListHandler_TestIP_InvalidID
--- PASS: TestAccessListHandler_TestIP_InvalidID (0.00s)
=== RUN   TestAccessListHandler_TestIP_MissingIPAddress
--- PASS: TestAccessListHandler_TestIP_MissingIPAddress (0.00s)
=== RUN   TestAccessListHandler_List_DBError

2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:129 [35;1mno such table: access_lists
[0m[33m[0.105ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` ORDER BY updated_at desc
--- PASS: TestAccessListHandler_List_DBError (0.00s)
=== RUN   TestAccessListHandler_Get_DBError

2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mno such table: access_lists
[0m[33m[0.095ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 1 ORDER BY `access_lists`.`id` LIMIT 1
--- PASS: TestAccessListHandler_Get_DBError (0.00s)
=== RUN   TestAccessListHandler_Delete_InternalError

2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:162 [35;1mno such table: proxy_hosts
[0m[33m[0.329ms] [34;1m[rows:0][0m SELECT count(*) FROM `proxy_hosts` WHERE access_list_id = 1
--- PASS: TestAccessListHandler_Delete_InternalError (0.00s)
=== RUN   TestAccessListHandler_Update_InvalidType
--- PASS: TestAccessListHandler_Update_InvalidType (0.00s)
=== RUN   TestAccessListHandler_Create_InvalidJSON
--- PASS: TestAccessListHandler_Create_InvalidJSON (0.00s)
=== RUN   TestAccessListHandler_TestIP_Blacklist
--- PASS: TestAccessListHandler_TestIP_Blacklist (0.00s)
=== RUN   TestAccessListHandler_TestIP_GeoWhitelist
--- PASS: TestAccessListHandler_TestIP_GeoWhitelist (0.01s)
=== RUN   TestAccessListHandler_TestIP_LocalNetworkOnly
--- PASS: TestAccessListHandler_TestIP_LocalNetworkOnly (0.00s)
=== RUN   TestAccessListHandler_TestIP_InternalError

2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mno such table: access_lists
[0m[33m[0.104ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 1 ORDER BY `access_lists`.`id` LIMIT 1
--- PASS: TestAccessListHandler_TestIP_InternalError (0.00s)
=== RUN   TestAccessListHandler_Create
=== RUN   TestAccessListHandler_Create/create_whitelist_successfully
=== RUN   TestAccessListHandler_Create/create_geo_whitelist_successfully
=== RUN   TestAccessListHandler_Create/create_local_network_only
=== RUN   TestAccessListHandler_Create/fail_with_invalid_type
=== RUN   TestAccessListHandler_Create/fail_with_missing_name
--- PASS: TestAccessListHandler_Create (0.00s)
    --- PASS: TestAccessListHandler_Create/create_whitelist_successfully (0.00s)
    --- PASS: TestAccessListHandler_Create/create_geo_whitelist_successfully (0.00s)
    --- PASS: TestAccessListHandler_Create/create_local_network_only (0.00s)
    --- PASS: TestAccessListHandler_Create/fail_with_invalid_type (0.00s)
    --- PASS: TestAccessListHandler_Create/fail_with_missing_name (0.00s)
=== RUN   TestAccessListHandler_List
--- PASS: TestAccessListHandler_List (0.00s)
=== RUN   TestAccessListHandler_Get
=== RUN   TestAccessListHandler_Get/get_existing_ACL
=== RUN   TestAccessListHandler_Get/get_non-existent_ACL

2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 9999 ORDER BY `access_lists`.`id` LIMIT 1
--- PASS: TestAccessListHandler_Get (0.00s)
    --- PASS: TestAccessListHandler_Get/get_existing_ACL (0.00s)
    --- PASS: TestAccessListHandler_Get/get_non-existent_ACL (0.00s)
=== RUN   TestAccessListHandler_Update
=== RUN   TestAccessListHandler_Update/update_successfully
=== RUN   TestAccessListHandler_Update/update_non-existent_ACL

2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 9999 ORDER BY `access_lists`.`id` LIMIT 1
--- PASS: TestAccessListHandler_Update (0.00s)
    --- PASS: TestAccessListHandler_Update/update_successfully (0.00s)
    --- PASS: TestAccessListHandler_Update/update_non-existent_ACL (0.00s)
=== RUN   TestAccessListHandler_Delete
=== RUN   TestAccessListHandler_Delete/delete_successfully
=== RUN   TestAccessListHandler_Delete/fail_to_delete_ACL_in_use
=== RUN   TestAccessListHandler_Delete/delete_non-existent_ACL
--- PASS: TestAccessListHandler_Delete (0.00s)
    --- PASS: TestAccessListHandler_Delete/delete_successfully (0.00s)
    --- PASS: TestAccessListHandler_Delete/fail_to_delete_ACL_in_use (0.00s)
    --- PASS: TestAccessListHandler_Delete/delete_non-existent_ACL (0.00s)
=== RUN   TestAccessListHandler_TestIP
=== RUN   TestAccessListHandler_TestIP/test_IP_in_whitelist
=== RUN   TestAccessListHandler_TestIP/test_IP_not_in_whitelist
=== RUN   TestAccessListHandler_TestIP/test_invalid_IP
=== RUN   TestAccessListHandler_TestIP/test_non-existent_ACL

2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 9999 ORDER BY `access_lists`.`id` LIMIT 1
--- PASS: TestAccessListHandler_TestIP (0.00s)
    --- PASS: TestAccessListHandler_TestIP/test_IP_in_whitelist (0.00s)
    --- PASS: TestAccessListHandler_TestIP/test_IP_not_in_whitelist (0.00s)
    --- PASS: TestAccessListHandler_TestIP/test_invalid_IP (0.00s)
    --- PASS: TestAccessListHandler_TestIP/test_non-existent_ACL (0.00s)
=== RUN   TestAccessListHandler_GetTemplates
--- PASS: TestAccessListHandler_GetTemplates (0.00s)
=== RUN   TestImportHandler_Commit_InvalidJSON
--- PASS: TestImportHandler_Commit_InvalidJSON (0.00s)
=== RUN   TestImportHandler_Commit_InvalidSessionUUID

2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
[0m[33m[0.048ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "passwd" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_Commit_InvalidSessionUUID (0.00s)
=== RUN   TestImportHandler_Commit_SessionNotFound

2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
[0m[33m[0.061ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "nonexistent-session" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_Commit_SessionNotFound (0.00s)
=== RUN   TestRemoteServerHandler_TestConnection_Unreachable
--- PASS: TestRemoteServerHandler_TestConnection_Unreachable (5.01s)
=== RUN   TestSecurityHandler_GetConfig_InternalError

2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mno such table: security_configs
[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_GetConfig_InternalError (0.00s)
=== RUN   TestSecurityHandler_UpdateConfig_ApplyCaddyError

2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "test" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_UpdateConfig_ApplyCaddyError (0.00s)
=== RUN   TestSecurityHandler_GenerateBreakGlass_Error

2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:121 [35;1mno such table: security_configs
[0m[33m[0.079ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_GenerateBreakGlass_Error (0.06s)
=== RUN   TestSecurityHandler_ListDecisions_Error

2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:178 [35;1mno such table: security_decisions
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc LIMIT 50
--- PASS: TestSecurityHandler_ListDecisions_Error (0.00s)
=== RUN   TestSecurityHandler_ListRuleSets_Error

2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:243 [35;1mno such table: security_rule_sets
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`
--- PASS: TestSecurityHandler_ListRuleSets_Error (0.00s)
=== RUN   TestSecurityHandler_UpsertRuleSet_Error

2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mno such table: security_rule_sets
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "test-ruleset" ORDER BY `security_rule_sets`.`id` LIMIT 1
--- PASS: TestSecurityHandler_UpsertRuleSet_Error (0.00s)
=== RUN   TestSecurityHandler_CreateDecision_LogError

2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:168 [35;1mno such table: security_decisions
[0m[33m[0.042ms] [34;1m[rows:0][0m INSERT INTO `security_decisions` (`uuid`,`source`,`action`,`ip`,`host`,`rule_id`,`details`,`created_at`) VALUES ("98eeedc9-a1f0-4dbf-b3a2-6558ed7ed345","manual","ban","192.168.1.1","","","","2025-12-12 19:05:38.782") RETURNING `id`
--- PASS: TestSecurityHandler_CreateDecision_LogError (0.00s)
=== RUN   TestSecurityHandler_DeleteRuleSet_Error

2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:234 [35;1mno such table: security_rule_sets
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE `security_rule_sets`.`id` = 999 ORDER BY `security_rule_sets`.`id` LIMIT 1
--- PASS: TestSecurityHandler_DeleteRuleSet_Error (0.00s)
=== RUN   TestCrowdsec_ImportConfig_EmptyUpload
--- PASS: TestCrowdsec_ImportConfig_EmptyUpload (0.00s)
=== RUN   TestBackupHandler_List_DBError
--- PASS: TestBackupHandler_List_DBError (0.00s)
=== RUN   TestImportHandler_UploadMulti_InvalidJSON
--- PASS: TestImportHandler_UploadMulti_InvalidJSON (0.00s)
=== RUN   TestImportHandler_UploadMulti_MissingCaddyfile
--- PASS: TestImportHandler_UploadMulti_MissingCaddyfile (0.00s)
=== RUN   TestImportHandler_UploadMulti_EmptyContent
--- PASS: TestImportHandler_UploadMulti_EmptyContent (0.00s)
=== RUN   TestImportHandler_UploadMulti_PathTraversal
--- PASS: TestImportHandler_UploadMulti_PathTraversal (0.00s)
=== RUN   TestLogsHandler_Download_PathTraversal
--- PASS: TestLogsHandler_Download_PathTraversal (0.00s)
=== RUN   TestLogsHandler_Download_NotFound
--- PASS: TestLogsHandler_Download_NotFound (0.00s)
=== RUN   TestLogsHandler_Download_Success
--- PASS: TestLogsHandler_Download_Success (0.00s)
=== RUN   TestImportHandler_Upload_InvalidJSON
time="2025-12-12T19:05:38Z" level=error msg="Import Upload: failed to bind JSON" error="invalid character 'o' in literal null (expecting 'u')"
--- PASS: TestImportHandler_Upload_InvalidJSON (0.00s)
=== RUN   TestImportHandler_Upload_EmptyContent
time="2025-12-12T19:05:38Z" level=error msg="Import Upload: failed to bind JSON" error="Key: 'Content' Error:Field validation for 'Content' failed on the 'required' tag"
--- PASS: TestImportHandler_Upload_EmptyContent (0.00s)
=== RUN   TestBackupHandler_List_ServiceError
--- PASS: TestBackupHandler_List_ServiceError (0.00s)
=== RUN   TestBackupHandler_Delete_PathTraversal
--- PASS: TestBackupHandler_Delete_PathTraversal (0.00s)
=== RUN   TestBackupHandler_Delete_InternalError2
--- PASS: TestBackupHandler_Delete_InternalError2 (0.00s)
=== RUN   TestRemoteServerHandler_TestConnection_NotFound2

2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "nonexistent-uuid" ORDER BY `remote_servers`.`id` LIMIT 1
--- PASS: TestRemoteServerHandler_TestConnection_NotFound2 (0.00s)
=== RUN   TestRemoteServerHandler_TestConnectionCustom_Unreachable2
--- PASS: TestRemoteServerHandler_TestConnectionCustom_Unreachable2 (5.00s)
=== RUN   TestAuthHandler_Register_InvalidJSON
--- PASS: TestAuthHandler_Register_InvalidJSON (0.00s)
=== RUN   TestHealthHandler_Basic
--- PASS: TestHealthHandler_Basic (0.00s)
=== RUN   TestBackupHandler_Create_Error
time="2025-12-12T19:05:43Z" level=error msg="Failed to create backup" action=create_backup error="database file not found: /tmp/TestBackupHandler_Create_Error2570738469/001/data/charon.db"
--- PASS: TestBackupHandler_Create_Error (0.00s)
=== RUN   TestSettingsHandler_GetSettings_Error

2025/12/12 19:05:43 [31;1m/projects/Charon/backend/internal/api/handlers/settings_handler.go:28 [35;1mno such table: settings
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings`
--- PASS: TestSettingsHandler_GetSettings_Error (0.00s)
=== RUN   TestSettingsHandler_UpdateSetting_InvalidJSON
--- PASS: TestSettingsHandler_UpdateSetting_InvalidJSON (0.00s)
=== RUN   TestRemoteServerHandler_TestConnection_Reachable
--- PASS: TestRemoteServerHandler_TestConnection_Reachable (0.00s)
=== RUN   TestRemoteServerHandler_TestConnection_EmptyHost
--- PASS: TestRemoteServerHandler_TestConnection_EmptyHost (0.00s)
=== RUN   TestImportHandler_UploadMulti_ValidCaddyfile
time="2025-12-12T19:05:43Z" level=error msg="Import UploadMulti: import failed" error="caddy adapt failed: exec: \"caddy\": executable file not found in $PATH (output: )" mainCaddyfile=Caddyfile preview="example.com { reverse_proxy localhost:8080 }"
--- PASS: TestImportHandler_UploadMulti_ValidCaddyfile (0.00s)
=== RUN   TestImportHandler_UploadMulti_SubdirFile
time="2025-12-12T19:05:43Z" level=error msg="Import UploadMulti: import failed" error="caddy adapt failed: exec: \"caddy\": executable file not found in $PATH (output: )" mainCaddyfile=Caddyfile preview="import sites/*"
--- PASS: TestImportHandler_UploadMulti_SubdirFile (0.00s)
=== RUN   TestAuthHandler_Login
--- PASS: TestAuthHandler_Login (0.14s)
=== RUN   TestSetSecureCookie_HTTPS_Strict
--- PASS: TestSetSecureCookie_HTTPS_Strict (0.00s)
=== RUN   TestSetSecureCookie_HTTP_Lax
--- PASS: TestSetSecureCookie_HTTP_Lax (0.00s)
=== RUN   TestAuthHandler_Login_Errors

2025/12/12 19:05:43 [31;1m/projects/Charon/backend/internal/services/auth_service.go:64 [35;1mrecord not found
[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE email = "nonexistent@example.com" ORDER BY `users`.`id` LIMIT 1
--- PASS: TestAuthHandler_Login_Errors (0.00s)
=== RUN   TestAuthHandler_Register
--- PASS: TestAuthHandler_Register (0.07s)
=== RUN   TestAuthHandler_Register_Duplicate

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/auth_service.go:54 [35;1mUNIQUE constraint failed: users.email
[0m[33m[0.303ms] [34;1m[rows:0][0m INSERT INTO `users` (`uuid`,`email`,`api_key`,`password_hash`,`name`,`role`,`enabled`,`failed_login_attempts`,`locked_until`,`last_login`,`invite_token`,`invite_expires`,`invited_at`,`invited_by`,`invite_status`,`permission_mode`,`created_at`,`updated_at`) VALUES ("2066b858-15a5-4e3e-a247-328d64408a45","dup@example.com","028e52ea-4eb3-4c1b-b7bd-eab0e113c993","$2a$10$mS9P7qy/pHxKUm7VnmiQhOnc8.OMl/z51Ods7bxSp4CCylswN2nlK","Dup User","user",true,0,NULL,NULL,"",NULL,NULL,NULL,"","allow_all","2025-12-12 19:05:44.028","2025-12-12 19:05:44.028") RETURNING `id`
--- PASS: TestAuthHandler_Register_Duplicate (0.07s)
=== RUN   TestAuthHandler_Logout
--- PASS: TestAuthHandler_Logout (0.00s)
=== RUN   TestAuthHandler_Me
--- PASS: TestAuthHandler_Me (0.00s)
=== RUN   TestAuthHandler_Me_NotFound

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/auth_service.go:147 [35;1mrecord not found
[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestAuthHandler_Me_NotFound (0.00s)
=== RUN   TestAuthHandler_ChangePassword
--- PASS: TestAuthHandler_ChangePassword (0.26s)
=== RUN   TestAuthHandler_ChangePassword_WrongOld
--- PASS: TestAuthHandler_ChangePassword_WrongOld (0.13s)
=== RUN   TestAuthHandler_ChangePassword_Errors
--- PASS: TestAuthHandler_ChangePassword_Errors (0.00s)
=== RUN   TestNewAuthHandlerWithDB
--- PASS: TestNewAuthHandlerWithDB (0.00s)
=== RUN   TestAuthHandler_Verify_NoCookie
--- PASS: TestAuthHandler_Verify_NoCookie (0.00s)
=== RUN   TestAuthHandler_Verify_InvalidToken
--- PASS: TestAuthHandler_Verify_InvalidToken (0.00s)
=== RUN   TestAuthHandler_Verify_ValidToken
--- PASS: TestAuthHandler_Verify_ValidToken (0.08s)
=== RUN   TestAuthHandler_Verify_BearerToken
--- PASS: TestAuthHandler_Verify_BearerToken (0.07s)
=== RUN   TestAuthHandler_Verify_DisabledUser
--- PASS: TestAuthHandler_Verify_DisabledUser (0.07s)
=== RUN   TestAuthHandler_Verify_ForwardAuthDenied
--- PASS: TestAuthHandler_Verify_ForwardAuthDenied (0.07s)
=== RUN   TestAuthHandler_VerifyStatus_NotAuthenticated
--- PASS: TestAuthHandler_VerifyStatus_NotAuthenticated (0.00s)
=== RUN   TestAuthHandler_VerifyStatus_InvalidToken
--- PASS: TestAuthHandler_VerifyStatus_InvalidToken (0.00s)
=== RUN   TestAuthHandler_VerifyStatus_Authenticated
--- PASS: TestAuthHandler_VerifyStatus_Authenticated (0.07s)
=== RUN   TestAuthHandler_VerifyStatus_DisabledUser
--- PASS: TestAuthHandler_VerifyStatus_DisabledUser (0.07s)
=== RUN   TestAuthHandler_GetAccessibleHosts_Unauthorized
--- PASS: TestAuthHandler_GetAccessibleHosts_Unauthorized (0.00s)
=== RUN   TestAuthHandler_GetAccessibleHosts_AllowAll
--- PASS: TestAuthHandler_GetAccessibleHosts_AllowAll (0.00s)
=== RUN   TestAuthHandler_GetAccessibleHosts_DenyAll
--- PASS: TestAuthHandler_GetAccessibleHosts_DenyAll (0.00s)
=== RUN   TestAuthHandler_GetAccessibleHosts_PermittedHosts
--- PASS: TestAuthHandler_GetAccessibleHosts_PermittedHosts (0.01s)
=== RUN   TestAuthHandler_GetAccessibleHosts_UserNotFound

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/api/handlers/auth_handler.go:334 [35;1mrecord not found
[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 99999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestAuthHandler_GetAccessibleHosts_UserNotFound (0.00s)
=== RUN   TestAuthHandler_CheckHostAccess_Unauthorized
--- PASS: TestAuthHandler_CheckHostAccess_Unauthorized (0.00s)
=== RUN   TestAuthHandler_CheckHostAccess_InvalidHostID
--- PASS: TestAuthHandler_CheckHostAccess_InvalidHostID (0.00s)
=== RUN   TestAuthHandler_CheckHostAccess_Allowed
--- PASS: TestAuthHandler_CheckHostAccess_Allowed (0.00s)
=== RUN   TestAuthHandler_CheckHostAccess_Denied
--- PASS: TestAuthHandler_CheckHostAccess_Denied (0.00s)
=== RUN   TestBackupHandlerSanitizesFilename
--- PASS: TestBackupHandlerSanitizesFilename (0.00s)
=== RUN   TestBackupLifecycle
--- PASS: TestBackupLifecycle (0.00s)
=== RUN   TestBackupHandler_Errors
--- PASS: TestBackupHandler_Errors (0.00s)
=== RUN   TestBackupHandler_List_Success
--- PASS: TestBackupHandler_List_Success (0.00s)
=== RUN   TestBackupHandler_Create_Success
--- PASS: TestBackupHandler_Create_Success (0.00s)
=== RUN   TestBackupHandler_Download_Success
--- PASS: TestBackupHandler_Download_Success (0.00s)
=== RUN   TestBackupHandler_PathTraversal
--- PASS: TestBackupHandler_PathTraversal (0.00s)
=== RUN   TestBackupHandler_Download_InvalidPath
--- PASS: TestBackupHandler_Download_InvalidPath (0.00s)
=== RUN   TestBackupHandler_Create_ServiceError
--- PASS: TestBackupHandler_Create_ServiceError (0.00s)
=== RUN   TestBackupHandler_Delete_InternalError
--- PASS: TestBackupHandler_Delete_InternalError (0.00s)
=== RUN   TestBackupHandler_Restore_InternalError
--- PASS: TestBackupHandler_Restore_InternalError (0.00s)
=== RUN   TestCertificateHandler_List_DBError

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:198 [35;1mno such table: ssl_certificates
[0m[33m[0.166ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE provider LIKE "letsencrypt%"

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:226 [35;1mno such table: ssl_certificates
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates`

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:226 [35;1mno such table: ssl_certificates
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates`
--- PASS: TestCertificateHandler_List_DBError (0.00s)
=== RUN   TestCertificateHandler_Delete_InvalidID

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:198 [35;1mno such table: ssl_certificates
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE provider LIKE "letsencrypt%"

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:226 [35;1mno such table: ssl_certificates
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates`
--- PASS: TestCertificateHandler_Delete_InvalidID (0.00s)
=== RUN   TestCertificateHandler_Delete_NotFound

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:410 [35;1mrecord not found
[0m[33m[0.061ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE `ssl_certificates`.`id` = 9999 ORDER BY `ssl_certificates`.`id` LIMIT 1
--- PASS: TestCertificateHandler_Delete_NotFound (0.00s)
=== RUN   TestCertificateHandler_Delete_NoBackupService

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:198 [35;1mno such table: ssl_certificates
[0m[33m[0.209ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE provider LIKE "letsencrypt%"

2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:226 [35;1mno such table: ssl_certificates
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates`
--- PASS: TestCertificateHandler_Delete_NoBackupService (0.20s)
=== RUN   TestCertificateHandler_Delete_CheckUsageDBError

2025/12/12 19:05:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:392 [35;1mno such table: proxy_hosts
[0m[33m[0.799ms] [34;1m[rows:0][0m SELECT count(*) FROM `proxy_hosts` WHERE certificate_id = 1
--- PASS: TestCertificateHandler_Delete_CheckUsageDBError (0.00s)
=== RUN   TestCertificateHandler_List_WithCertificates

2025/12/12 19:05:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.411ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
--- PASS: TestCertificateHandler_List_WithCertificates (0.00s)
=== RUN   TestCertificateHandler_Delete_RequiresAuth
--- PASS: TestCertificateHandler_Delete_RequiresAuth (0.00s)
=== RUN   TestCertificateHandler_List_RequiresAuth
--- PASS: TestCertificateHandler_List_RequiresAuth (0.00s)
=== RUN   TestCertificateHandler_Upload_RequiresAuth
--- PASS: TestCertificateHandler_Upload_RequiresAuth (0.00s)
=== RUN   TestCertificateHandler_Delete_DiskSpaceCheck
--- PASS: TestCertificateHandler_Delete_DiskSpaceCheck (0.00s)
=== RUN   TestCertificateHandler_Delete_NotificationRateLimiting
--- PASS: TestCertificateHandler_Delete_NotificationRateLimiting (0.00s)
=== RUN   TestDeleteCertificate_InUse
--- PASS: TestDeleteCertificate_InUse (0.00s)
=== RUN   TestDeleteCertificate_CreatesBackup

2025/12/12 19:05:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:441 [35;1mdatabase table is locked: ssl_certificates
[0m[33m[0.059ms] [34;1m[rows:0][0m DELETE FROM `ssl_certificates` WHERE id = 1
    certificate_handler_test.go:125: expected 200 OK, got 500, body={"error":"failed to delete certificate"}
--- FAIL: TestDeleteCertificate_CreatesBackup (0.00s)
=== RUN   TestDeleteCertificate_BackupFailure
--- PASS: TestDeleteCertificate_BackupFailure (0.00s)
=== RUN   TestDeleteCertificate_InUse_NoBackup
--- PASS: TestDeleteCertificate_InUse_NoBackup (0.00s)
=== RUN   TestCertificateHandler_List
--- PASS: TestCertificateHandler_List (0.00s)
=== RUN   TestCertificateHandler_Upload_MissingName
--- PASS: TestCertificateHandler_Upload_MissingName (0.00s)
=== RUN   TestCertificateHandler_Upload_MissingCertFile
--- PASS: TestCertificateHandler_Upload_MissingCertFile (0.00s)
=== RUN   TestCertificateHandler_Upload_MissingKeyFile
--- PASS: TestCertificateHandler_Upload_MissingKeyFile (0.00s)
=== RUN   TestCertificateHandler_Upload_Success
--- PASS: TestCertificateHandler_Upload_Success (0.05s)
=== RUN   TestBackupHandlerQuick
--- PASS: TestBackupHandlerQuick (0.00s)
=== RUN   TestListPresetsShowsCachedStatus
--- PASS: TestListPresetsShowsCachedStatus (0.37s)
=== RUN   TestCacheKeyPersistence
--- PASS: TestCacheKeyPersistence (0.00s)
=== RUN   TestListDecisions_Success
--- PASS: TestListDecisions_Success (0.00s)
=== RUN   TestListDecisions_EmptyList
--- PASS: TestListDecisions_EmptyList (0.00s)
=== RUN   TestListDecisions_CscliError
--- PASS: TestListDecisions_CscliError (0.00s)
=== RUN   TestListDecisions_InvalidJSON
--- PASS: TestListDecisions_InvalidJSON (0.00s)
=== RUN   TestBanIP_Success
--- PASS: TestBanIP_Success (0.00s)
=== RUN   TestBanIP_DefaultDuration
--- PASS: TestBanIP_DefaultDuration (0.00s)
=== RUN   TestBanIP_MissingIP
--- PASS: TestBanIP_MissingIP (0.00s)
=== RUN   TestBanIP_EmptyIP
--- PASS: TestBanIP_EmptyIP (0.00s)
=== RUN   TestBanIP_CscliError
--- PASS: TestBanIP_CscliError (0.00s)
=== RUN   TestUnbanIP_Success
--- PASS: TestUnbanIP_Success (0.00s)
=== RUN   TestUnbanIP_CscliError
--- PASS: TestUnbanIP_CscliError (0.00s)
=== RUN   TestListDecisions_MultipleDecisions
--- PASS: TestListDecisions_MultipleDecisions (0.00s)
=== RUN   TestBanIP_InvalidJSON
--- PASS: TestBanIP_InvalidJSON (0.00s)
=== RUN   TestDefaultCrowdsecExecutorPidFile
--- PASS: TestDefaultCrowdsecExecutorPidFile (0.00s)
=== RUN   TestDefaultCrowdsecExecutorStartStatusStop
--- PASS: TestDefaultCrowdsecExecutorStartStatusStop (0.20s)
=== RUN   TestDefaultCrowdsecExecutor_Status_NoPidFile
--- PASS: TestDefaultCrowdsecExecutor_Status_NoPidFile (0.00s)
=== RUN   TestDefaultCrowdsecExecutor_Status_InvalidPid
--- PASS: TestDefaultCrowdsecExecutor_Status_InvalidPid (0.00s)
=== RUN   TestDefaultCrowdsecExecutor_Status_NonExistentProcess
--- PASS: TestDefaultCrowdsecExecutor_Status_NonExistentProcess (0.00s)
=== RUN   TestDefaultCrowdsecExecutor_Stop_NoPidFile
--- PASS: TestDefaultCrowdsecExecutor_Stop_NoPidFile (0.00s)
=== RUN   TestDefaultCrowdsecExecutor_Stop_InvalidPid
--- PASS: TestDefaultCrowdsecExecutor_Stop_InvalidPid (0.00s)
=== RUN   TestDefaultCrowdsecExecutor_Stop_NonExistentProcess
--- PASS: TestDefaultCrowdsecExecutor_Stop_NonExistentProcess (0.00s)
=== RUN   TestDefaultCrowdsecExecutor_Start_InvalidBinary
--- PASS: TestDefaultCrowdsecExecutor_Start_InvalidBinary (0.00s)
=== RUN   TestCrowdsec_Start_Error
--- PASS: TestCrowdsec_Start_Error (0.00s)
=== RUN   TestCrowdsec_Stop_Error
--- PASS: TestCrowdsec_Stop_Error (0.00s)
=== RUN   TestCrowdsec_Status_Error
--- PASS: TestCrowdsec_Status_Error (0.00s)
=== RUN   TestCrowdsec_ReadFile_MissingPath
--- PASS: TestCrowdsec_ReadFile_MissingPath (0.00s)
=== RUN   TestCrowdsec_ReadFile_PathTraversal
--- PASS: TestCrowdsec_ReadFile_PathTraversal (0.00s)
=== RUN   TestCrowdsec_ReadFile_NotFound
--- PASS: TestCrowdsec_ReadFile_NotFound (0.00s)
=== RUN   TestCrowdsec_WriteFile_InvalidPayload
--- PASS: TestCrowdsec_WriteFile_InvalidPayload (0.00s)
=== RUN   TestCrowdsec_WriteFile_MissingPath
--- PASS: TestCrowdsec_WriteFile_MissingPath (0.00s)
=== RUN   TestCrowdsec_WriteFile_PathTraversal
--- PASS: TestCrowdsec_WriteFile_PathTraversal (0.00s)
=== RUN   TestCrowdsec_ExportConfig_NotFound
--- PASS: TestCrowdsec_ExportConfig_NotFound (0.00s)
=== RUN   TestCrowdsec_ListFiles_EmptyDir
--- PASS: TestCrowdsec_ListFiles_EmptyDir (0.00s)
=== RUN   TestCrowdsec_ListFiles_NonExistent
--- PASS: TestCrowdsec_ListFiles_NonExistent (0.00s)
=== RUN   TestCrowdsec_ImportConfig_NoFile
--- PASS: TestCrowdsec_ImportConfig_NoFile (0.00s)
=== RUN   TestCrowdsec_ReadFile_NestedPath
--- PASS: TestCrowdsec_ReadFile_NestedPath (0.00s)
=== RUN   TestCrowdsec_WriteFile_Success
--- PASS: TestCrowdsec_WriteFile_Success (0.00s)
=== RUN   TestCrowdsec_ListPresets_Disabled
--- PASS: TestCrowdsec_ListPresets_Disabled (0.00s)
=== RUN   TestCrowdsec_ListPresets_Success
--- PASS: TestCrowdsec_ListPresets_Success (0.19s)
=== RUN   TestCrowdsec_PullPreset_Validation
--- PASS: TestCrowdsec_PullPreset_Validation (0.00s)
=== RUN   TestCrowdsec_ApplyPreset_Validation
--- PASS: TestCrowdsec_ApplyPreset_Validation (0.00s)
=== RUN   TestCrowdsecEndpoints
--- PASS: TestCrowdsecEndpoints (0.00s)
=== RUN   TestImportConfig
--- PASS: TestImportConfig (0.00s)
=== RUN   TestImportCreatesBackup
--- PASS: TestImportCreatesBackup (0.00s)
=== RUN   TestExportConfig
--- PASS: TestExportConfig (0.00s)
=== RUN   TestListAndReadFile
--- PASS: TestListAndReadFile (0.00s)
=== RUN   TestExportConfigStreamsArchive
--- PASS: TestExportConfigStreamsArchive (0.00s)
=== RUN   TestWriteFileCreatesBackup
--- PASS: TestWriteFileCreatesBackup (0.00s)
=== RUN   TestListPresetsCerberusDisabled
--- PASS: TestListPresetsCerberusDisabled (0.00s)
=== RUN   TestReadFileInvalidPath
--- PASS: TestReadFileInvalidPath (0.00s)
=== RUN   TestWriteFileInvalidPath
--- PASS: TestWriteFileInvalidPath (0.00s)
=== RUN   TestWriteFileMissingPath
--- PASS: TestWriteFileMissingPath (0.00s)
=== RUN   TestWriteFileInvalidPayload
--- PASS: TestWriteFileInvalidPayload (0.00s)
=== RUN   TestImportConfigRequiresFile
--- PASS: TestImportConfigRequiresFile (0.00s)
=== RUN   TestImportConfigRejectsEmptyUpload
--- PASS: TestImportConfigRejectsEmptyUpload (0.00s)
=== RUN   TestListFilesMissingDir
--- PASS: TestListFilesMissingDir (0.00s)
=== RUN   TestListFilesReturnsEntries
--- PASS: TestListFilesReturnsEntries (0.00s)
=== RUN   TestIsCerberusEnabledFromDB
--- PASS: TestIsCerberusEnabledFromDB (0.00s)
=== RUN   TestIsCerberusEnabledInvalidEnv
--- PASS: TestIsCerberusEnabledInvalidEnv (0.00s)
=== RUN   TestIsCerberusEnabledLegacyEnv
--- PASS: TestIsCerberusEnabledLegacyEnv (0.00s)
=== RUN   TestConsoleEnrollDisabled
--- PASS: TestConsoleEnrollDisabled (0.00s)
=== RUN   TestConsoleEnrollServiceUnavailable
--- PASS: TestConsoleEnrollServiceUnavailable (0.00s)
=== RUN   TestConsoleEnrollInvalidPayload
--- PASS: TestConsoleEnrollInvalidPayload (0.00s)
=== RUN   TestConsoleEnrollSuccess

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.056ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/security_service.go:195 [35;1mno such table: security_audits
[0m[33m[0.077ms] [34;1m[rows:0][0m INSERT INTO `security_audits` (`uuid`,`actor`,`action`,`details`,`created_at`) VALUES ("6331bcc9-8eb8-427c-8839-ea8b70681f2f","unknown","crowdsec_console_enroll_succeeded","status=enrolled tenant=my-tenant agent=test-agent correlation_id=35cd7e38-b6e0-4cae-9db1-1b9a0e0b3790","2025-12-12 19:05:46.084") RETURNING `id`
--- PASS: TestConsoleEnrollSuccess (0.00s)
=== RUN   TestConsoleEnrollMissingAgentName

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/security_service.go:195 [35;1mno such table: security_audits
[0m[33m[0.128ms] [34;1m[rows:0][0m INSERT INTO `security_audits` (`uuid`,`actor`,`action`,`details`,`created_at`) VALUES ("67c730e1-fbe5-418e-ac88-16b135d4a3dd","unknown","crowdsec_console_enroll_failed","status= tenant= agent= correlation_id=","2025-12-12 19:05:46.085") RETURNING `id`
--- PASS: TestConsoleEnrollMissingAgentName (0.00s)
=== RUN   TestConsoleStatusDisabled
--- PASS: TestConsoleStatusDisabled (0.00s)
=== RUN   TestConsoleStatusServiceUnavailable
--- PASS: TestConsoleStatusServiceUnavailable (0.00s)
=== RUN   TestConsoleStatusSuccess

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
--- PASS: TestConsoleStatusSuccess (0.00s)
=== RUN   TestConsoleStatusAfterEnroll

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/security_service.go:195 [35;1mno such table: security_audits
[0m[33m[0.127ms] [34;1m[rows:0][0m INSERT INTO `security_audits` (`uuid`,`actor`,`action`,`details`,`created_at`) VALUES ("bcef394b-34a9-4834-9336-2f211122795a","unknown","crowdsec_console_enroll_succeeded","status=enrolled tenant= agent=test-agent correlation_id=30e6cca4-d985-4900-8711-eb46782b995a","2025-12-12 19:05:46.089") RETURNING `id`
--- PASS: TestConsoleStatusAfterEnroll (0.00s)
=== RUN   TestIsConsoleEnrollmentEnabledFromDB
--- PASS: TestIsConsoleEnrollmentEnabledFromDB (0.00s)
=== RUN   TestIsConsoleEnrollmentDisabledFromDB
--- PASS: TestIsConsoleEnrollmentDisabledFromDB (0.00s)
=== RUN   TestIsConsoleEnrollmentEnabledFromEnv
--- PASS: TestIsConsoleEnrollmentEnabledFromEnv (0.00s)
=== RUN   TestIsConsoleEnrollmentDisabledFromEnv
--- PASS: TestIsConsoleEnrollmentDisabledFromEnv (0.00s)
=== RUN   TestIsConsoleEnrollmentInvalidEnv
--- PASS: TestIsConsoleEnrollmentInvalidEnv (0.00s)
=== RUN   TestIsConsoleEnrollmentDefaultDisabled
--- PASS: TestIsConsoleEnrollmentDefaultDisabled (0.00s)
=== RUN   TestIsConsoleEnrollmentDBTrueVariants
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/true
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/TRUE
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/True
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/1
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/yes
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/YES
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/false
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/FALSE
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/0
=== RUN   TestIsConsoleEnrollmentDBTrueVariants/no
--- PASS: TestIsConsoleEnrollmentDBTrueVariants (0.01s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/true (0.00s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/TRUE (0.00s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/True (0.00s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/1 (0.00s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/yes (0.00s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/YES (0.00s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/false (0.00s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/FALSE (0.00s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/0 (0.00s)
    --- PASS: TestIsConsoleEnrollmentDBTrueVariants/no (0.00s)
=== RUN   TestActorFromContextWithUserID
--- PASS: TestActorFromContextWithUserID (0.00s)
=== RUN   TestActorFromContextWithNumericUserID
--- PASS: TestActorFromContextWithNumericUserID (0.00s)
=== RUN   TestActorFromContextNoUser
--- PASS: TestActorFromContextNoUser (0.00s)
=== RUN   TestTTLRemainingSeconds
--- PASS: TestTTLRemainingSeconds (0.00s)
=== RUN   TestTTLRemainingSecondsExpired
--- PASS: TestTTLRemainingSecondsExpired (0.00s)
=== RUN   TestTTLRemainingSecondsZeroTime
--- PASS: TestTTLRemainingSecondsZeroTime (0.00s)
=== RUN   TestTTLRemainingSecondsZeroTTL
--- PASS: TestTTLRemainingSecondsZeroTTL (0.00s)
=== RUN   TestHubEndpointsNil
--- PASS: TestHubEndpointsNil (0.00s)
=== RUN   TestHubEndpointsDeduplicates
--- PASS: TestHubEndpointsDeduplicates (0.00s)
=== RUN   TestHubEndpointsMultiple
--- PASS: TestHubEndpointsMultiple (0.00s)
=== RUN   TestHubEndpointsSkipsEmpty
--- PASS: TestHubEndpointsSkipsEmpty (0.00s)
=== RUN   TestGetLAPIDecisions_FallbackToCscli
--- PASS: TestGetLAPIDecisions_FallbackToCscli (0.00s)
=== RUN   TestGetLAPIDecisions_EmptyResponse
--- PASS: TestGetLAPIDecisions_EmptyResponse (0.00s)
=== RUN   TestCheckLAPIHealth_Handler
--- PASS: TestCheckLAPIHealth_Handler (0.00s)
=== RUN   TestGetLAPIKey_FromEnv
--- PASS: TestGetLAPIKey_FromEnv (0.00s)
=== RUN   TestGetLAPIKey_Empty
--- PASS: TestGetLAPIKey_Empty (0.00s)
=== RUN   TestListPresetsIncludesCacheAndIndex
--- PASS: TestListPresetsIncludesCacheAndIndex (0.00s)
=== RUN   TestPullPresetHandlerSuccess
--- PASS: TestPullPresetHandlerSuccess (0.00s)
=== RUN   TestApplyPresetHandlerAudits
--- PASS: TestApplyPresetHandlerAudits (0.01s)
=== RUN   TestPullPresetHandlerHubError
--- PASS: TestPullPresetHandlerHubError (0.00s)
=== RUN   TestPullPresetHandlerTimeout
--- PASS: TestPullPresetHandlerTimeout (0.00s)
=== RUN   TestGetCachedPresetNotFound
--- PASS: TestGetCachedPresetNotFound (0.00s)
=== RUN   TestGetCachedPresetServiceUnavailable
--- PASS: TestGetCachedPresetServiceUnavailable (0.00s)
=== RUN   TestApplyPresetHandlerBackupFailure
--- PASS: TestApplyPresetHandlerBackupFailure (0.00s)
=== RUN   TestListPresetsMergesCuratedAndHub
--- PASS: TestListPresetsMergesCuratedAndHub (0.00s)
=== RUN   TestGetCachedPresetSuccess
--- PASS: TestGetCachedPresetSuccess (0.00s)
=== RUN   TestGetCachedPresetSlugRequired
--- PASS: TestGetCachedPresetSlugRequired (0.00s)
=== RUN   TestGetCachedPresetPreviewError
--- PASS: TestGetCachedPresetPreviewError (0.00s)
=== RUN   TestPullCuratedPresetSkipsHub
--- PASS: TestPullCuratedPresetSkipsHub (0.00s)
=== RUN   TestApplyCuratedPresetSkipsHub
--- PASS: TestApplyCuratedPresetSkipsHub (0.00s)
=== RUN   TestPullThenApplyIntegration
    crowdsec_pull_apply_integration_test.go:67: User pulls preset
    crowdsec_pull_apply_integration_test.go:83: Pull succeeded, cache_key: test/preset-1765566346
    crowdsec_pull_apply_integration_test.go:90: Cache verified, slug: test/preset
    crowdsec_pull_apply_integration_test.go:93: User applies preset

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/crowdsec_handler.go:725 [35;1mno such table: crowdsec_preset_events
[0m[33m[0.106ms] [34;1m[rows:0][0m INSERT INTO `crowdsec_preset_events` (`slug`,`action`,`status`,`cache_key`,`backup_path`,`error`,`created_at`,`updated_at`) VALUES ("test/preset","apply","applied","test/preset-1765566346","/tmp/TestPullThenApplyIntegration3897446452/002.backup.20251212-190546","","2025-12-12 19:05:46.133","2025-12-12 19:05:46.133") RETURNING `id`
    crowdsec_pull_apply_integration_test.go:109: Apply succeeded, backup: /tmp/TestPullThenApplyIntegration3897446452/002.backup.20251212-190546
--- PASS: TestPullThenApplyIntegration (0.00s)
=== RUN   TestApplyWithoutPullReturnsProperError
    crowdsec_pull_apply_integration_test.go:138: User tries to apply preset without pulling first

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/crowdsec_handler.go:695 [35;1mno such table: crowdsec_preset_events
[0m[33m[0.178ms] [34;1m[rows:0][0m INSERT INTO `crowdsec_preset_events` (`slug`,`action`,`status`,`cache_key`,`backup_path`,`error`,`created_at`,`updated_at`) VALUES ("test/preset","apply","failed","","/tmp/TestApplyWithoutPullReturnsProperError3560971172/002.backup.20251212-190546","load cache for test/preset: load cache for test/preset: cache miss: refresh cache: fetch hub index: http://test.hub/api/index.json: http://test.hub/api/index.json (status 500)
https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json (status 500)
https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json (status 500)
https://hub-data.crowdsec.net/api/index.json: https://hub-data.crowdsec.net/api/index.json (status 500)","2025-12-12 19:05:46.134","2025-12-12 19:05:46.134") RETURNING `id`
    crowdsec_pull_apply_integration_test.go:154: Proper error message returned: Preset cache missing or expired. Pull the preset again, then retry apply.
--- PASS: TestApplyWithoutPullReturnsProperError (0.00s)
=== RUN   TestApplyRollbackWhenCacheMissingAndRepullFails

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/crowdsec_handler.go:695 [35;1mno such table: crowdsec_preset_events
[0m[33m[0.099ms] [34;1m[rows:0][0m INSERT INTO `crowdsec_preset_events` (`slug`,`action`,`status`,`cache_key`,`backup_path`,`error`,`created_at`,`updated_at`) VALUES ("missing/preset","apply","failed","","/tmp/TestApplyRollbackWhenCacheMissingAndRepullFails4135574716/002/crowdsec.backup.20251212-190546","load cache for missing/preset: load cache for missing/preset: cache miss: refresh cache: fetch hub index: http://test.hub/api/index.json: http://test.hub/api/index.json (status 500)
https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json (status 500)
https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json (status 500)
https://hub-data.crowdsec.net/api/index.json: https://hub-data.crowdsec.net/api/index.json (status 500)","2025-12-12 19:05:46.136","2025-12-12 19:05:46.136") RETURNING `id`
--- PASS: TestApplyRollbackWhenCacheMissingAndRepullFails (0.00s)
=== RUN   TestDockerHandler_ListContainers
--- PASS: TestDockerHandler_ListContainers (0.00s)
=== RUN   TestDockerHandler_ListContainers_NonExistentServerID

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent-uuid" ORDER BY `remote_servers`.`id` LIMIT 1
--- PASS: TestDockerHandler_ListContainers_NonExistentServerID (0.00s)
=== RUN   TestDockerHandler_ListContainers_WithServerID
--- PASS: TestDockerHandler_ListContainers_WithServerID (0.00s)
=== RUN   TestDockerHandler_ListContainers_WithHostQuery
--- PASS: TestDockerHandler_ListContainers_WithHostQuery (0.00s)
=== RUN   TestDockerHandler_RegisterRoutes
--- PASS: TestDockerHandler_RegisterRoutes (0.00s)
=== RUN   TestDockerHandler_NewDockerHandler
--- PASS: TestDockerHandler_NewDockerHandler (0.00s)
=== RUN   TestDomainLifecycle
--- PASS: TestDomainLifecycle (0.00s)
=== RUN   TestDomainErrors
--- PASS: TestDomainErrors (0.00s)
=== RUN   TestDomainDelete_NotFound

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:73 [35;1mrecord not found
[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `domains` WHERE uuid = "nonexistent-uuid" AND `domains`.`deleted_at` IS NULL ORDER BY `domains`.`id` LIMIT 1
--- PASS: TestDomainDelete_NotFound (0.00s)
=== RUN   TestDomainCreate_Duplicate

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:49 [35;1mUNIQUE constraint failed: domains.name
[0m[33m[0.087ms] [34;1m[rows:0][0m INSERT INTO `domains` (`uuid`,`name`,`created_at`,`updated_at`,`deleted_at`) VALUES ("30ded0b1-7423-4851-95fb-9c48e4a9bb59","duplicate.com","2025-12-12 19:05:46.158","2025-12-12 19:05:46.158",NULL) RETURNING `id`
--- PASS: TestDomainCreate_Duplicate (0.00s)
=== RUN   TestDomainList_Empty
--- PASS: TestDomainList_Empty (0.00s)
=== RUN   TestDomainCreate_LongName
--- PASS: TestDomainCreate_LongName (0.00s)
=== RUN   TestFeatureFlagsHandler_GetFlags_DBPrecedence

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlagsHandler_GetFlags_DBPrecedence (0.00s)
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvFallback

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlagsHandler_GetFlags_EnvFallback (0.00s)
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvShortForm

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlagsHandler_GetFlags_EnvShortForm (0.00s)
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvNumeric

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlagsHandler_GetFlags_EnvNumeric (0.00s)
=== RUN   TestFeatureFlagsHandler_GetFlags_DefaultTrue

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlagsHandler_GetFlags_DefaultTrue (0.00s)
=== RUN   TestFeatureFlagsHandler_GetFlags_AllDefaultFlagsPresent

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlagsHandler_GetFlags_AllDefaultFlagsPresent (0.00s)
=== RUN   TestFeatureFlagsHandler_UpdateFlags_Success
--- PASS: TestFeatureFlagsHandler_UpdateFlags_Success (0.00s)
=== RUN   TestFeatureFlagsHandler_UpdateFlags_Upsert
--- PASS: TestFeatureFlagsHandler_UpdateFlags_Upsert (0.00s)
=== RUN   TestFeatureFlagsHandler_UpdateFlags_InvalidJSON
--- PASS: TestFeatureFlagsHandler_UpdateFlags_InvalidJSON (0.00s)
=== RUN   TestFeatureFlagsHandler_UpdateFlags_OnlyAllowedKeys

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler_coverage_test.go:296 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.invalid.key" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlagsHandler_UpdateFlags_OnlyAllowedKeys (0.00s)
=== RUN   TestFeatureFlagsHandler_UpdateFlags_EmptyPayload
--- PASS: TestFeatureFlagsHandler_UpdateFlags_EmptyPayload (0.00s)
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/lowercase_true

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/uppercase_TRUE

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.040ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/mixed_case_True

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/numeric_1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.035ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/yes

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/YES_uppercase

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.055ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/lowercase_false

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/numeric_0

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/no

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/empty_string

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/random_string

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.362ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/whitespace_padded_true

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_DBValueVariants/whitespace_padded_false

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants (0.01s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/lowercase_true (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/uppercase_TRUE (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/mixed_case_True (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/numeric_1 (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/yes (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/YES_uppercase (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/lowercase_false (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/numeric_0 (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/no (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/empty_string (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/random_string (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/whitespace_padded_true (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/whitespace_padded_false (0.00s)
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvValueVariants
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvValueVariants/true_string

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvValueVariants/TRUE_uppercase

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvValueVariants/1_numeric

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvValueVariants/false_string

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvValueVariants/FALSE_uppercase

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvValueVariants/0_numeric

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
=== RUN   TestFeatureFlagsHandler_GetFlags_EnvValueVariants/invalid_value_defaults_to_numeric_check

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/true_string (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/TRUE_uppercase (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/1_numeric (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/false_string (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/FALSE_uppercase (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/0_numeric (0.00s)
    --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/invalid_value_defaults_to_numeric_check (0.00s)
=== RUN   TestFeatureFlagsHandler_UpdateFlags_BoolValues
=== RUN   TestFeatureFlagsHandler_UpdateFlags_BoolValues/true
=== RUN   TestFeatureFlagsHandler_UpdateFlags_BoolValues/false
--- PASS: TestFeatureFlagsHandler_UpdateFlags_BoolValues (0.00s)
    --- PASS: TestFeatureFlagsHandler_UpdateFlags_BoolValues/true (0.00s)
    --- PASS: TestFeatureFlagsHandler_UpdateFlags_BoolValues/false (0.00s)
=== RUN   TestFeatureFlagsHandler_NewFeatureFlagsHandler
--- PASS: TestFeatureFlagsHandler_NewFeatureFlagsHandler (0.00s)
=== RUN   TestFeatureFlags_GetAndUpdate

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.053ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlags_GetAndUpdate (0.00s)
=== RUN   TestFeatureFlags_EnvFallback

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mno such table: settings
[0m[33m[0.056ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mno such table: settings
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mno such table: settings
[0m[33m[0.005ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestFeatureFlags_EnvFallback (0.00s)
=== RUN   TestHealthHandler
--- PASS: TestHealthHandler (0.00s)
=== RUN   TestGetLocalIP
    health_handler_test.go:36: getLocalIP returned: "217.15.170.144"
--- PASS: TestGetLocalIP (0.00s)
=== RUN   TestIsSafePathUnderBase
--- PASS: TestIsSafePathUnderBase (0.00s)
=== RUN   TestImportUploadSanitizesFilename
--- PASS: TestImportUploadSanitizesFilename (0.00s)
=== RUN   TestLogsHandler_Read_FilterBySearch
--- PASS: TestLogsHandler_Read_FilterBySearch (0.00s)
=== RUN   TestLogsHandler_Read_FilterByHost
--- PASS: TestLogsHandler_Read_FilterByHost (0.00s)
=== RUN   TestLogsHandler_Read_FilterByLevel
--- PASS: TestLogsHandler_Read_FilterByLevel (0.00s)
=== RUN   TestLogsHandler_Read_FilterByStatus
--- PASS: TestLogsHandler_Read_FilterByStatus (0.00s)
=== RUN   TestLogsHandler_Read_SortAsc
--- PASS: TestLogsHandler_Read_SortAsc (0.00s)
=== RUN   TestLogsHandler_List_DirectoryIsFile
--- PASS: TestLogsHandler_List_DirectoryIsFile (0.00s)
=== RUN   TestLogsHandler_Download_TempFileError
--- PASS: TestLogsHandler_Download_TempFileError (0.00s)
=== RUN   TestLogsLifecycle
--- PASS: TestLogsLifecycle (0.00s)
=== RUN   TestLogsHandler_PathTraversal
--- PASS: TestLogsHandler_PathTraversal (0.00s)
=== RUN   TestLogsWebSocketHandler_SuccessfulConnection
--- PASS: TestLogsWebSocketHandler_SuccessfulConnection (0.00s)
=== RUN   TestLogsWebSocketHandler_ReceiveLogEntries
--- PASS: TestLogsWebSocketHandler_ReceiveLogEntries (0.00s)
=== RUN   TestLogsWebSocketHandler_LevelFilter
--- PASS: TestLogsWebSocketHandler_LevelFilter (0.15s)
=== RUN   TestLogsWebSocketHandler_SourceFilter
--- PASS: TestLogsWebSocketHandler_SourceFilter (0.00s)
=== RUN   TestLogsWebSocketHandler_CombinedFilters
--- PASS: TestLogsWebSocketHandler_CombinedFilters (0.00s)
=== RUN   TestLogsWebSocketHandler_CaseInsensitiveFilters
--- PASS: TestLogsWebSocketHandler_CaseInsensitiveFilters (0.00s)
=== RUN   TestLogsWebSocketHandler_UpgradeFailure
--- PASS: TestLogsWebSocketHandler_UpgradeFailure (0.00s)
=== RUN   TestLogsWebSocketHandler_ClientDisconnect
--- PASS: TestLogsWebSocketHandler_ClientDisconnect (0.02s)
=== RUN   TestLogsWebSocketHandler_ChannelClosed
--- PASS: TestLogsWebSocketHandler_ChannelClosed (0.00s)
=== RUN   TestLogsWebSocketHandler_MultipleConnections
--- PASS: TestLogsWebSocketHandler_MultipleConnections (0.00s)
=== RUN   TestLogsWebSocketHandler_HighVolumeLogging
--- PASS: TestLogsWebSocketHandler_HighVolumeLogging (0.02s)
=== RUN   TestLogsWebSocketHandler_EmptyLogFields
--- PASS: TestLogsWebSocketHandler_EmptyLogFields (0.00s)
=== RUN   TestLogsWebSocketHandler_SubscriberIDUniqueness
--- PASS: TestLogsWebSocketHandler_SubscriberIDUniqueness (0.00s)
=== RUN   TestLogsWebSocketHandler_WithRealLogger
--- PASS: TestLogsWebSocketHandler_WithRealLogger (0.00s)
=== RUN   TestLogsWebSocketHandler_ConnectionLifecycle
--- PASS: TestLogsWebSocketHandler_ConnectionLifecycle (0.00s)
=== RUN   TestDomainHandler_List_Error

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:28 [35;1mno such table: domains
[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `domains` WHERE `domains`.`deleted_at` IS NULL ORDER BY name asc
--- PASS: TestDomainHandler_List_Error (0.00s)
=== RUN   TestDomainHandler_Create_InvalidJSON
--- PASS: TestDomainHandler_Create_InvalidJSON (0.00s)
=== RUN   TestDomainHandler_Create_DBError

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:49 [35;1mno such table: domains
[0m[33m[0.068ms] [34;1m[rows:0][0m INSERT INTO `domains` (`uuid`,`name`,`created_at`,`updated_at`,`deleted_at`) VALUES ("078a32f2-b134-4709-9687-40e22ddc4715","example.com","2025-12-12 19:05:46.4","2025-12-12 19:05:46.4",NULL) RETURNING `id`
--- PASS: TestDomainHandler_Create_DBError (0.00s)
=== RUN   TestDomainHandler_Delete_Error

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:73 [35;1mno such table: domains
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `domains` WHERE uuid = "test-id" AND `domains`.`deleted_at` IS NULL ORDER BY `domains`.`id` LIMIT 1

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:88 [35;1mno such table: domains
[0m[33m[0.065ms] [34;1m[rows:0][0m UPDATE `domains` SET `deleted_at`="2025-12-12 19:05:46.401" WHERE uuid = "test-id" AND `domains`.`deleted_at` IS NULL
--- PASS: TestDomainHandler_Delete_Error (0.00s)
=== RUN   TestRemoteServerHandler_List_Error

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:92 [35;1mno such table: remote_servers
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` ORDER BY name ASC
--- PASS: TestRemoteServerHandler_List_Error (0.00s)
=== RUN   TestRemoteServerHandler_List_EnabledOnly

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/misc_coverage_test.go:131 [35;1mUNIQUE constraint failed: remote_servers.uuid
[0m[33m[0.041ms] [34;1m[rows:0][0m INSERT INTO `remote_servers` (`uuid`,`name`,`provider`,`host`,`port`,`scheme`,`tags`,`description`,`enabled`,`last_checked`,`reachable`,`created_at`,`updated_at`) VALUES ("","Server2","","localhost",22,"","","",true,NULL,false,"2025-12-12 19:05:46.402","2025-12-12 19:05:46.402") RETURNING `id`
--- PASS: TestRemoteServerHandler_List_EnabledOnly (0.00s)
=== RUN   TestRemoteServerHandler_Update_NotFound

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "nonexistent" ORDER BY `remote_servers`.`id` LIMIT 1
--- PASS: TestRemoteServerHandler_Update_NotFound (0.00s)
=== RUN   TestRemoteServerHandler_Update_InvalidJSON
--- PASS: TestRemoteServerHandler_Update_InvalidJSON (0.00s)
=== RUN   TestRemoteServerHandler_TestConnection_NotFound

2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "nonexistent" ORDER BY `remote_servers`.`id` LIMIT 1
--- PASS: TestRemoteServerHandler_TestConnection_NotFound (0.00s)
=== RUN   TestRemoteServerHandler_TestConnectionCustom_InvalidJSON
--- PASS: TestRemoteServerHandler_TestConnectionCustom_InvalidJSON (0.00s)
=== RUN   TestRemoteServerHandler_TestConnectionCustom_Unreachable
--- PASS: TestRemoteServerHandler_TestConnectionCustom_Unreachable (5.00s)
=== RUN   TestUptimeHandler_List_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:863 [35;1mno such table: uptime_monitors
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` ORDER BY name ASC
--- PASS: TestUptimeHandler_List_Error (0.00s)
=== RUN   TestUptimeHandler_GetHistory_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:877 [35;1mno such table: uptime_heartbeats
[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `uptime_heartbeats` WHERE monitor_id = "test-id" ORDER BY created_at desc LIMIT 50
--- PASS: TestUptimeHandler_GetHistory_Error (0.00s)
=== RUN   TestUptimeHandler_Update_InvalidJSON
--- PASS: TestUptimeHandler_Update_InvalidJSON (0.00s)
=== RUN   TestUptimeHandler_Sync_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:105 [35;1mno such table: proxy_hosts
[0m[33m[0.271ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
--- PASS: TestUptimeHandler_Sync_Error (0.00s)
=== RUN   TestUptimeHandler_Delete_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:911 [35;1mno such table: uptime_monitors
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "test-id" ORDER BY `uptime_monitors`.`id` LIMIT 1
--- PASS: TestUptimeHandler_Delete_Error (0.00s)
=== RUN   TestUptimeHandler_CheckMonitor_NotFound

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:869 [35;1mrecord not found
[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "nonexistent" ORDER BY `uptime_monitors`.`id` LIMIT 1
--- PASS: TestUptimeHandler_CheckMonitor_NotFound (0.00s)
=== RUN   TestNotificationHandler_List_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:66 [35;1mno such table: notifications
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `notifications` ORDER BY created_at desc
--- PASS: TestNotificationHandler_List_Error (0.00s)
=== RUN   TestNotificationHandler_List_UnreadOnly
--- PASS: TestNotificationHandler_List_UnreadOnly (0.00s)
=== RUN   TestNotificationHandler_MarkAsRead_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:71 [35;1mno such table: notifications
[0m[33m[0.039ms] [34;1m[rows:0][0m UPDATE `notifications` SET `read`=true WHERE id = "test-id"
--- PASS: TestNotificationHandler_MarkAsRead_Error (0.00s)
=== RUN   TestNotificationHandler_MarkAllAsRead_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:75 [35;1mno such table: notifications
[0m[33m[0.031ms] [34;1m[rows:0][0m UPDATE `notifications` SET `read`=true WHERE read = false
--- PASS: TestNotificationHandler_MarkAllAsRead_Error (0.00s)
=== RUN   TestNotificationProviderHandler_List_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:455 [35;1mno such table: notification_providers
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `notification_providers`
--- PASS: TestNotificationProviderHandler_List_Error (0.00s)
=== RUN   TestNotificationProviderHandler_Create_InvalidJSON
--- PASS: TestNotificationProviderHandler_Create_InvalidJSON (0.00s)
=== RUN   TestNotificationProviderHandler_Create_DBError

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:468 [35;1mno such table: notification_providers
[0m[33m[0.058ms] [34;1m[rows:0][0m INSERT INTO `notification_providers` (`id`,`name`,`type`,`url`,`config`,`template`,`enabled`,`notify_proxy_hosts`,`notify_remote_servers`,`notify_domains`,`notify_certs`,`notify_uptime`,`created_at`,`updated_at`) VALUES ("513248aa-8301-4798-8a21-c87b3eaef859","Test","webhook","https://example.com","","minimal",false,true,true,true,true,true,"2025-12-12 19:05:51.418","2025-12-12 19:05:51.418")
--- PASS: TestNotificationProviderHandler_Create_DBError (0.00s)
=== RUN   TestNotificationProviderHandler_Create_InvalidTemplate
--- PASS: TestNotificationProviderHandler_Create_InvalidTemplate (0.00s)
=== RUN   TestNotificationProviderHandler_Update_InvalidJSON
--- PASS: TestNotificationProviderHandler_Update_InvalidJSON (0.00s)
=== RUN   TestNotificationProviderHandler_Update_InvalidTemplate
--- PASS: TestNotificationProviderHandler_Update_InvalidTemplate (0.00s)
=== RUN   TestNotificationProviderHandler_Update_DBError

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:479 [35;1mno such table: notification_providers
[0m[33m[0.068ms] [34;1m[rows:0][0m UPDATE `notification_providers` SET `name`="Test",`type`="webhook",`url`="https://example.com",`config`="",`template`="minimal",`enabled`=false,`notify_proxy_hosts`=false,`notify_remote_servers`=false,`notify_domains`=false,`notify_certs`=false,`notify_uptime`=false,`created_at`="0000-00-00 00:00:00",`updated_at`="2025-12-12 19:05:51.422" WHERE `id` = "test-id"
--- PASS: TestNotificationProviderHandler_Update_DBError (0.00s)
=== RUN   TestNotificationProviderHandler_Delete_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:483 [35;1mno such table: notification_providers
[0m[33m[0.032ms] [34;1m[rows:0][0m DELETE FROM `notification_providers` WHERE id = "test-id"
--- PASS: TestNotificationProviderHandler_Delete_Error (0.00s)
=== RUN   TestNotificationProviderHandler_Test_InvalidJSON
--- PASS: TestNotificationProviderHandler_Test_InvalidJSON (0.00s)
=== RUN   TestNotificationProviderHandler_Templates
--- PASS: TestNotificationProviderHandler_Templates (0.00s)
=== RUN   TestNotificationProviderHandler_Preview_InvalidJSON
--- PASS: TestNotificationProviderHandler_Preview_InvalidJSON (0.00s)
=== RUN   TestNotificationProviderHandler_Preview_WithData
--- PASS: TestNotificationProviderHandler_Preview_WithData (0.00s)
=== RUN   TestNotificationProviderHandler_Preview_InvalidTemplate
--- PASS: TestNotificationProviderHandler_Preview_InvalidTemplate (0.00s)
=== RUN   TestNotificationTemplateHandler_List_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:375 [35;1mno such table: notification_templates
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `notification_templates` ORDER BY created_at desc
--- PASS: TestNotificationTemplateHandler_List_Error (0.00s)
=== RUN   TestNotificationTemplateHandler_Create_BadJSON
--- PASS: TestNotificationTemplateHandler_Create_BadJSON (0.00s)
=== RUN   TestNotificationTemplateHandler_Create_DBError

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:392 [35;1mno such table: notification_templates
[0m[33m[0.040ms] [34;1m[rows:0][0m INSERT INTO `notification_templates` (`id`,`name`,`description`,`config`,`template`,`created_at`,`updated_at`) VALUES ("ca832d3a-64c5-42a4-8c75-b389bf4048ff","Test","","{""test"": true}","minimal","2025-12-12 19:05:51.429","2025-12-12 19:05:51.429")
--- PASS: TestNotificationTemplateHandler_Create_DBError (0.00s)
=== RUN   TestNotificationTemplateHandler_Update_BadJSON
--- PASS: TestNotificationTemplateHandler_Update_BadJSON (0.00s)
=== RUN   TestNotificationTemplateHandler_Update_DBError

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:397 [35;1mno such table: notification_templates
[0m[33m[0.037ms] [34;1m[rows:0][0m UPDATE `notification_templates` SET `name`="Test",`description`="",`config`="{""test"": true}",`template`="",`created_at`="0000-00-00 00:00:00",`updated_at`="2025-12-12 19:05:51.431" WHERE `id` = "test-id"
--- PASS: TestNotificationTemplateHandler_Update_DBError (0.00s)
=== RUN   TestNotificationTemplateHandler_Delete_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:402 [35;1mno such table: notification_templates
[0m[33m[0.029ms] [34;1m[rows:0][0m DELETE FROM `notification_templates` WHERE id = "test-id"
--- PASS: TestNotificationTemplateHandler_Delete_Error (0.00s)
=== RUN   TestNotificationTemplateHandler_Preview_BadJSON
--- PASS: TestNotificationTemplateHandler_Preview_BadJSON (0.00s)
=== RUN   TestNotificationTemplateHandler_Preview_TemplateNotFound

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:384 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `notification_templates` WHERE id = "nonexistent" ORDER BY `notification_templates`.`id` LIMIT 1
--- PASS: TestNotificationTemplateHandler_Preview_TemplateNotFound (0.00s)
=== RUN   TestNotificationTemplateHandler_Preview_WithStoredTemplate
--- PASS: TestNotificationTemplateHandler_Preview_WithStoredTemplate (0.00s)
=== RUN   TestNotificationTemplateHandler_Preview_InvalidTemplate
--- PASS: TestNotificationTemplateHandler_Preview_InvalidTemplate (0.00s)
=== RUN   TestNotificationTemplateHandler_CRUDAndPreview
--- PASS: TestNotificationTemplateHandler_CRUDAndPreview (0.00s)
=== RUN   TestNotificationTemplateHandler_Create_InvalidJSON
--- PASS: TestNotificationTemplateHandler_Create_InvalidJSON (0.00s)
=== RUN   TestNotificationTemplateHandler_Update_InvalidJSON
--- PASS: TestNotificationTemplateHandler_Update_InvalidJSON (0.00s)
=== RUN   TestNotificationTemplateHandler_Preview_InvalidJSON
--- PASS: TestNotificationTemplateHandler_Preview_InvalidJSON (0.00s)
=== RUN   TestPerf_GetStatus_AssertThreshold
    perf_assert_test.go:107: GetStatus avg=0.045ms p95=0.085ms max=1.550ms
--- PASS: TestPerf_GetStatus_AssertThreshold (0.02s)
=== RUN   TestPerf_GetStatus_Parallel_AssertThreshold
    perf_assert_test.go:150: GetStatus Parallel avg=0.067ms p95=0.135ms max=3.510ms
--- PASS: TestPerf_GetStatus_Parallel_AssertThreshold (0.02s)
=== RUN   TestPerf_ListDecisions_AssertThreshold
    perf_assert_test.go:179: ListDecisions avg=0.863ms p95=1.108ms max=3.795ms
--- PASS: TestPerf_ListDecisions_AssertThreshold (0.22s)
=== RUN   TestProxyHostLifecycle

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "f4e8da5e-4668-40da-95b8-db6151890005" ORDER BY `proxy_hosts`.`id` LIMIT 1
--- PASS: TestProxyHostLifecycle (0.00s)
=== RUN   TestProxyHostDelete_WithUptimeCleanup

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:82 [35;1mno such table: notification_providers
[0m[33m[0.132ms] [34;1m[rows:0][0m SELECT * FROM `notification_providers` WHERE enabled = true

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/proxy_host_handler_test.go:141 [35;1mrecord not found
[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "ph-delete-1" ORDER BY `proxy_hosts`.`id` LIMIT 1
--- PASS: TestProxyHostDelete_WithUptimeCleanup (0.00s)
=== RUN   TestProxyHostErrors

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.106ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.055ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.045ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "non-existent-uuid" ORDER BY `proxy_hosts`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "non-existent-uuid" ORDER BY `proxy_hosts`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "non-existent-uuid" ORDER BY `proxy_hosts`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.004ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestProxyHostErrors (0.01s)
=== RUN   TestProxyHostValidation
--- PASS: TestProxyHostValidation (0.00s)
=== RUN   TestProxyHostCreate_AdvancedConfig_InvalidJSON
--- PASS: TestProxyHostCreate_AdvancedConfig_InvalidJSON (0.00s)
=== RUN   TestProxyHostCreate_AdvancedConfig_Normalization
--- PASS: TestProxyHostCreate_AdvancedConfig_Normalization (0.00s)
=== RUN   TestProxyHostUpdate_CertificateID_Null
--- PASS: TestProxyHostUpdate_CertificateID_Null (0.00s)
=== RUN   TestProxyHostConnection
--- PASS: TestProxyHostConnection (0.00s)
=== RUN   TestProxyHostHandler_List_Error

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:121 [35;1msql: database is closed
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` ORDER BY updated_at desc
--- PASS: TestProxyHostHandler_List_Error (0.00s)
=== RUN   TestProxyHostWithCaddyIntegration

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.134ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.060ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:82 [35;1mno such table: notification_providers
[0m[33m[0.122ms] [34;1m[rows:0][0m SELECT * FROM `notification_providers` WHERE enabled = true

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.005ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.005ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:82 [35;1mno such table: notification_providers
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `notification_providers` WHERE enabled = true
--- PASS: TestProxyHostWithCaddyIntegration (0.01s)
=== RUN   TestProxyHostHandler_BulkUpdateACL_Success
--- PASS: TestProxyHostHandler_BulkUpdateACL_Success (0.00s)
=== RUN   TestProxyHostHandler_BulkUpdateACL_RemoveACL
--- PASS: TestProxyHostHandler_BulkUpdateACL_RemoveACL (0.00s)
=== RUN   TestProxyHostHandler_BulkUpdateACL_PartialFailure

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "422c0cc1-e09e-4e7f-8ba4-6c678835580a" ORDER BY `proxy_hosts`.`id` LIMIT 1
--- PASS: TestProxyHostHandler_BulkUpdateACL_PartialFailure (0.00s)
=== RUN   TestProxyHostHandler_BulkUpdateACL_EmptyUUIDs
--- PASS: TestProxyHostHandler_BulkUpdateACL_EmptyUUIDs (0.00s)
=== RUN   TestProxyHostHandler_BulkUpdateACL_InvalidJSON
--- PASS: TestProxyHostHandler_BulkUpdateACL_InvalidJSON (0.00s)
=== RUN   TestProxyHostUpdate_AdvancedConfig_ClearAndBackup
--- PASS: TestProxyHostUpdate_AdvancedConfig_ClearAndBackup (0.00s)
=== RUN   TestProxyHostUpdate_AdvancedConfig_InvalidJSON
--- PASS: TestProxyHostUpdate_AdvancedConfig_InvalidJSON (0.00s)
=== RUN   TestProxyHostUpdate_SetCertificateID
--- PASS: TestProxyHostUpdate_SetCertificateID (0.00s)
=== RUN   TestProxyHostUpdate_AdvancedConfig_SetBackup
--- PASS: TestProxyHostUpdate_AdvancedConfig_SetBackup (0.00s)
=== RUN   TestProxyHostUpdate_ForwardPort_StringValue
--- PASS: TestProxyHostUpdate_ForwardPort_StringValue (0.00s)
=== RUN   TestProxyHostUpdate_Locations_InvalidPayload
--- PASS: TestProxyHostUpdate_Locations_InvalidPayload (0.00s)
=== RUN   TestProxyHostUpdate_SetBooleansAndApplication
--- PASS: TestProxyHostUpdate_SetBooleansAndApplication (0.00s)
=== RUN   TestProxyHostUpdate_Locations_Replace
--- PASS: TestProxyHostUpdate_Locations_Replace (0.00s)
=== RUN   TestProxyHostCreate_WithCertificateAndLocations
--- PASS: TestProxyHostCreate_WithCertificateAndLocations (0.00s)
=== RUN   TestSanitizeForLog
--- PASS: TestSanitizeForLog (0.00s)
=== RUN   TestSecurityHandler_GetGeoIPStatus_NotInitialized
--- PASS: TestSecurityHandler_GetGeoIPStatus_NotInitialized (0.00s)
=== RUN   TestSecurityHandler_GetGeoIPStatus_Initialized_NotLoaded
--- PASS: TestSecurityHandler_GetGeoIPStatus_Initialized_NotLoaded (0.00s)
=== RUN   TestSecurityHandler_ReloadGeoIP_NotInitialized
--- PASS: TestSecurityHandler_ReloadGeoIP_NotInitialized (0.00s)
=== RUN   TestSecurityHandler_ReloadGeoIP_LoadError
time="2025-12-12T19:05:51Z" level=error msg="Failed to reload GeoIP database" error="open : no such file or directory"
--- PASS: TestSecurityHandler_ReloadGeoIP_LoadError (0.00s)
=== RUN   TestSecurityHandler_LookupGeoIP_MissingIPAddress
--- PASS: TestSecurityHandler_LookupGeoIP_MissingIPAddress (0.00s)
=== RUN   TestSecurityHandler_LookupGeoIP_ServiceUnavailable
--- PASS: TestSecurityHandler_LookupGeoIP_ServiceUnavailable (0.00s)
=== RUN   TestSecurityHandler_GetConfigAndUpdateConfig

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_GetConfigAndUpdateConfig (0.00s)
=== RUN   TestSecurityHandler_GetStatus_SQLInjection
--- PASS: TestSecurityHandler_GetStatus_SQLInjection (0.00s)
=== RUN   TestSecurityHandler_CreateDecision_SQLInjection
=== RUN   TestSecurityHandler_CreateDecision_SQLInjection/payload_0
=== RUN   TestSecurityHandler_CreateDecision_SQLInjection/payload_1
=== RUN   TestSecurityHandler_CreateDecision_SQLInjection/payload_2
=== RUN   TestSecurityHandler_CreateDecision_SQLInjection/payload_3
--- PASS: TestSecurityHandler_CreateDecision_SQLInjection (0.00s)
    --- PASS: TestSecurityHandler_CreateDecision_SQLInjection/payload_0 (0.00s)
    --- PASS: TestSecurityHandler_CreateDecision_SQLInjection/payload_1 (0.00s)
    --- PASS: TestSecurityHandler_CreateDecision_SQLInjection/payload_2 (0.00s)
    --- PASS: TestSecurityHandler_CreateDecision_SQLInjection/payload_3 (0.00s)
=== RUN   TestSecurityHandler_UpsertRuleSet_MassivePayload
--- PASS: TestSecurityHandler_UpsertRuleSet_MassivePayload (0.05s)
=== RUN   TestSecurityHandler_UpsertRuleSet_EmptyName
--- PASS: TestSecurityHandler_UpsertRuleSet_EmptyName (0.00s)
=== RUN   TestSecurityHandler_CreateDecision_EmptyFields
=== RUN   TestSecurityHandler_CreateDecision_EmptyFields/empty_ip
=== RUN   TestSecurityHandler_CreateDecision_EmptyFields/empty_action
=== RUN   TestSecurityHandler_CreateDecision_EmptyFields/both_empty
=== RUN   TestSecurityHandler_CreateDecision_EmptyFields/valid
--- PASS: TestSecurityHandler_CreateDecision_EmptyFields (0.00s)
    --- PASS: TestSecurityHandler_CreateDecision_EmptyFields/empty_ip (0.00s)
    --- PASS: TestSecurityHandler_CreateDecision_EmptyFields/empty_action (0.00s)
    --- PASS: TestSecurityHandler_CreateDecision_EmptyFields/both_empty (0.00s)
    --- PASS: TestSecurityHandler_CreateDecision_EmptyFields/valid (0.00s)
=== RUN   TestSecurityHandler_GetStatus_SettingsOverride
--- PASS: TestSecurityHandler_GetStatus_SettingsOverride (0.00s)
=== RUN   TestSecurityHandler_GetStatus_DisabledViaSettings
--- PASS: TestSecurityHandler_GetStatus_DisabledViaSettings (0.00s)
=== RUN   TestSecurityAudit_DeleteRuleSet_InvalidID
=== RUN   TestSecurityAudit_DeleteRuleSet_InvalidID/empty_id
=== RUN   TestSecurityAudit_DeleteRuleSet_InvalidID/non_numeric
=== RUN   TestSecurityAudit_DeleteRuleSet_InvalidID/negative
=== RUN   TestSecurityAudit_DeleteRuleSet_InvalidID/sql_injection
=== RUN   TestSecurityAudit_DeleteRuleSet_InvalidID/not_found
--- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID (0.00s)
    --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/empty_id (0.00s)
    --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/non_numeric (0.00s)
    --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/negative (0.00s)
    --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/sql_injection (0.00s)
    --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/not_found (0.00s)
=== RUN   TestSecurityHandler_UpsertRuleSet_XSSInContent
--- PASS: TestSecurityHandler_UpsertRuleSet_XSSInContent (0.00s)
=== RUN   TestSecurityHandler_UpdateConfig_RateLimitBounds
=== RUN   TestSecurityHandler_UpdateConfig_RateLimitBounds/valid_limits
=== RUN   TestSecurityHandler_UpdateConfig_RateLimitBounds/zero_requests
=== RUN   TestSecurityHandler_UpdateConfig_RateLimitBounds/negative_burst
=== RUN   TestSecurityHandler_UpdateConfig_RateLimitBounds/huge_values
--- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds (0.00s)
    --- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds/valid_limits (0.00s)
    --- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds/zero_requests (0.00s)
    --- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds/negative_burst (0.00s)
    --- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds/huge_values (0.00s)
=== RUN   TestSecurityHandler_GetStatus_NilDB
--- PASS: TestSecurityHandler_GetStatus_NilDB (0.00s)
=== RUN   TestSecurityHandler_Enable_WithoutWhitelist
--- PASS: TestSecurityHandler_Enable_WithoutWhitelist (0.00s)
=== RUN   TestSecurityHandler_Disable_RequiresToken
--- PASS: TestSecurityHandler_Disable_RequiresToken (0.00s)
=== RUN   TestSecurityHandler_GetStatus_CrowdSecModeValidation
=== RUN   TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_remote
=== RUN   TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_external
=== RUN   TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_cloud
=== RUN   TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_api
=== RUN   TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_../../../etc/passwd
--- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation (0.00s)
    --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_remote (0.00s)
    --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_external (0.00s)
    --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_cloud (0.00s)
    --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_api (0.00s)
    --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_../../../etc/passwd (0.00s)
=== RUN   TestSecurityHandler_GetStatus_Clean
--- PASS: TestSecurityHandler_GetStatus_Clean (0.00s)
=== RUN   TestSecurityHandler_Cerberus_DBOverride

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.138ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_Cerberus_DBOverride (0.00s)
=== RUN   TestSecurityHandler_ACL_DBOverride

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
    security_handler_clean_test.go:119:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_clean_test.go:119
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_ACL_DBOverride
--- FAIL: TestSecurityHandler_ACL_DBOverride (0.00s)
=== RUN   TestSecurityHandler_GenerateBreakGlass_ReturnsToken

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/security_service.go:121 [35;1mrecord not found
[0m[33m[0.131ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_GenerateBreakGlass_ReturnsToken (0.06s)
=== RUN   TestSecurityHandler_ACL_DisabledWhenCerberusOff

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.070ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_ACL_DisabledWhenCerberusOff (0.00s)
=== RUN   TestSecurityHandler_CrowdSec_Mode_DBOverride

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.054ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
    security_handler_clean_test.go:196:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_clean_test.go:196
        	Error:      	Not equal:
        	            	expected: "local"
        	            	actual  : "disabled"

        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -1 +1 @@
        	            	-local
        	            	+disabled
        	Test:       	TestSecurityHandler_CrowdSec_Mode_DBOverride
--- FAIL: TestSecurityHandler_CrowdSec_Mode_DBOverride (0.00s)
=== RUN   TestSecurityHandler_CrowdSec_ExternalMappedToDisabled_DBOverride

2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_CrowdSec_ExternalMappedToDisabled_DBOverride (0.00s)
=== RUN   TestSecurityHandler_ExternalModeMappedToDisabled
--- PASS: TestSecurityHandler_ExternalModeMappedToDisabled (0.00s)
=== RUN   TestSecurityHandler_Enable_Disable_WithAdminWhitelistAndToken
--- PASS: TestSecurityHandler_Enable_Disable_WithAdminWhitelistAndToken (0.12s)
=== RUN   TestSecurityHandler_UpdateConfig_Success

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_UpdateConfig_Success (0.00s)
=== RUN   TestSecurityHandler_UpdateConfig_DefaultName

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_UpdateConfig_DefaultName (0.00s)
=== RUN   TestSecurityHandler_UpdateConfig_InvalidPayload
--- PASS: TestSecurityHandler_UpdateConfig_InvalidPayload (0.00s)
=== RUN   TestSecurityHandler_GetConfig_Success
--- PASS: TestSecurityHandler_GetConfig_Success (0.00s)
=== RUN   TestSecurityHandler_GetConfig_NotFound

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_GetConfig_NotFound (0.00s)
=== RUN   TestSecurityHandler_ListDecisions_Success
--- PASS: TestSecurityHandler_ListDecisions_Success (0.00s)
=== RUN   TestSecurityHandler_ListDecisions_WithLimit
--- PASS: TestSecurityHandler_ListDecisions_WithLimit (0.00s)
=== RUN   TestSecurityHandler_CreateDecision_Success
--- PASS: TestSecurityHandler_CreateDecision_Success (0.00s)
=== RUN   TestSecurityHandler_CreateDecision_MissingIP
--- PASS: TestSecurityHandler_CreateDecision_MissingIP (0.00s)
=== RUN   TestSecurityHandler_CreateDecision_MissingAction
--- PASS: TestSecurityHandler_CreateDecision_MissingAction (0.00s)
=== RUN   TestSecurityHandler_CreateDecision_InvalidPayload
--- PASS: TestSecurityHandler_CreateDecision_InvalidPayload (0.00s)
=== RUN   TestSecurityHandler_ListRuleSets_Success
--- PASS: TestSecurityHandler_ListRuleSets_Success (0.00s)
=== RUN   TestSecurityHandler_UpsertRuleSet_Success

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mrecord not found
[0m[33m[0.037ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "test-ruleset" ORDER BY `security_rule_sets`.`id` LIMIT 1
--- PASS: TestSecurityHandler_UpsertRuleSet_Success (0.00s)
=== RUN   TestSecurityHandler_UpsertRuleSet_MissingName
--- PASS: TestSecurityHandler_UpsertRuleSet_MissingName (0.00s)
=== RUN   TestSecurityHandler_UpsertRuleSet_InvalidPayload
--- PASS: TestSecurityHandler_UpsertRuleSet_InvalidPayload (0.00s)
=== RUN   TestSecurityHandler_DeleteRuleSet_Success
--- PASS: TestSecurityHandler_DeleteRuleSet_Success (0.00s)
=== RUN   TestSecurityHandler_DeleteRuleSet_NotFound

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:234 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE `security_rule_sets`.`id` = 999 ORDER BY `security_rule_sets`.`id` LIMIT 1
--- PASS: TestSecurityHandler_DeleteRuleSet_NotFound (0.00s)
=== RUN   TestSecurityHandler_DeleteRuleSet_InvalidID
--- PASS: TestSecurityHandler_DeleteRuleSet_InvalidID (0.00s)
=== RUN   TestSecurityHandler_DeleteRuleSet_EmptyID
--- PASS: TestSecurityHandler_DeleteRuleSet_EmptyID (0.00s)
=== RUN   TestSecurityHandler_Enable_NoConfigNoWhitelist

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.083ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.126ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_Enable_NoConfigNoWhitelist (0.00s)
=== RUN   TestSecurityHandler_Enable_WithWhitelist
--- PASS: TestSecurityHandler_Enable_WithWhitelist (0.00s)
=== RUN   TestSecurityHandler_Enable_IPNotInWhitelist
--- PASS: TestSecurityHandler_Enable_IPNotInWhitelist (0.00s)
=== RUN   TestSecurityHandler_Enable_WithValidBreakGlassToken
--- PASS: TestSecurityHandler_Enable_WithValidBreakGlassToken (0.12s)
=== RUN   TestSecurityHandler_Enable_WithInvalidBreakGlassToken
--- PASS: TestSecurityHandler_Enable_WithInvalidBreakGlassToken (0.00s)
=== RUN   TestSecurityHandler_Disable_FromLocalhost
--- PASS: TestSecurityHandler_Disable_FromLocalhost (0.00s)
=== RUN   TestSecurityHandler_Disable_FromRemoteWithToken
--- PASS: TestSecurityHandler_Disable_FromRemoteWithToken (0.12s)
=== RUN   TestSecurityHandler_Disable_FromRemoteNoToken
--- PASS: TestSecurityHandler_Disable_FromRemoteNoToken (0.00s)
=== RUN   TestSecurityHandler_Disable_FromRemoteInvalidToken
--- PASS: TestSecurityHandler_Disable_FromRemoteInvalidToken (0.00s)
=== RUN   TestSecurityHandler_GenerateBreakGlass_NoConfig

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:121 [35;1mrecord not found
[0m[33m[0.137ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_GenerateBreakGlass_NoConfig (0.06s)
=== RUN   TestSecurityHandler_Disable_FromIPv6Localhost
--- PASS: TestSecurityHandler_Disable_FromIPv6Localhost (0.00s)
=== RUN   TestSecurityHandler_Enable_WithCIDRWhitelist
--- PASS: TestSecurityHandler_Enable_WithCIDRWhitelist (0.00s)
=== RUN   TestSecurityHandler_Enable_WithExactIPWhitelist
--- PASS: TestSecurityHandler_Enable_WithExactIPWhitelist (0.00s)
=== RUN   TestSecurityHandler_GetStatus_Fixed
=== RUN   TestSecurityHandler_GetStatus_Fixed/All_Disabled
=== RUN   TestSecurityHandler_GetStatus_Fixed/All_Enabled
--- PASS: TestSecurityHandler_GetStatus_Fixed (0.00s)
    --- PASS: TestSecurityHandler_GetStatus_Fixed/All_Disabled (0.00s)
    --- PASS: TestSecurityHandler_GetStatus_Fixed/All_Enabled (0.00s)
=== RUN   TestSecurityHandler_CreateAndListDecisionAndRulesets

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mrecord not found
[0m[33m[0.062ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "owasp-crs" ORDER BY `security_rule_sets`.`id` LIMIT 1
--- PASS: TestSecurityHandler_CreateAndListDecisionAndRulesets (0.07s)
=== RUN   TestSecurityHandler_UpsertDeleteTriggersApplyConfig

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mrecord not found
[0m[33m[0.045ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "owasp-crs" ORDER BY `security_rule_sets`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestSecurityHandler_UpsertDeleteTriggersApplyConfig (0.01s)
=== RUN   TestSecurityHandler_GetStatus_RespectsSettingsTable
=== RUN   TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_enabled_via_settings_overrides_disabled_config

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.114ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
    security_handler_settings_test.go:145:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:145
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_enabled_via_settings_overrides_disabled_config
        	Messages:   	WAF enabled mismatch
=== RUN   TestSecurityHandler_GetStatus_RespectsSettingsTable/Rate_Limit_enabled_via_settings_overrides_disabled_config

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
    security_handler_settings_test.go:149:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:149
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_GetStatus_RespectsSettingsTable/Rate_Limit_enabled_via_settings_overrides_disabled_config
        	Messages:   	Rate Limit enabled mismatch
=== RUN   TestSecurityHandler_GetStatus_RespectsSettingsTable/CrowdSec_enabled_via_settings_overrides_disabled_config

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.037ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
    security_handler_settings_test.go:153:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:153
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_GetStatus_RespectsSettingsTable/CrowdSec_enabled_via_settings_overrides_disabled_config
        	Messages:   	CrowdSec enabled mismatch
=== RUN   TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
    security_handler_settings_test.go:145:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:145
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings
        	Messages:   	WAF enabled mismatch
    security_handler_settings_test.go:149:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:149
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings
        	Messages:   	Rate Limit enabled mismatch
    security_handler_settings_test.go:153:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:153
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings
        	Messages:   	CrowdSec enabled mismatch
=== RUN   TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_disabled_via_settings_overrides_enabled_config

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
=== RUN   TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled)

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
    security_handler_settings_test.go:145:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:145
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled)
        	Messages:   	WAF enabled mismatch
    security_handler_settings_test.go:149:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:149
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled)
        	Messages:   	Rate Limit enabled mismatch
    security_handler_settings_test.go:153:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:153
        	Error:      	Not equal:
        	            	expected: true
        	            	actual  : false
        	Test:       	TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled)
        	Messages:   	CrowdSec enabled mismatch
--- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable (0.01s)
    --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_enabled_via_settings_overrides_disabled_config (0.00s)
    --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/Rate_Limit_enabled_via_settings_overrides_disabled_config (0.00s)
    --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/CrowdSec_enabled_via_settings_overrides_disabled_config (0.00s)
    --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings (0.00s)
    --- PASS: TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_disabled_via_settings_overrides_enabled_config (0.00s)
    --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled) (0.00s)
=== RUN   TestSecurityHandler_GetStatus_WAFModeFromSettings

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.049ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
    security_handler_settings_test.go:187:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:187
        	Error:      	Should be true
        	Test:       	TestSecurityHandler_GetStatus_WAFModeFromSettings
--- FAIL: TestSecurityHandler_GetStatus_WAFModeFromSettings (0.01s)
=== RUN   TestSecurityHandler_GetStatus_RateLimitModeFromSettings

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
    security_handler_settings_test.go:218:
        	Error Trace:	/projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:218
        	Error:      	Should be true
        	Test:       	TestSecurityHandler_GetStatus_RateLimitModeFromSettings
--- FAIL: TestSecurityHandler_GetStatus_RateLimitModeFromSettings (0.00s)
=== RUN   TestSecurityHandler_GetWAFExclusions_Empty

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_GetWAFExclusions_Empty (0.00s)
=== RUN   TestSecurityHandler_GetWAFExclusions_WithExclusions
--- PASS: TestSecurityHandler_GetWAFExclusions_WithExclusions (0.00s)
=== RUN   TestSecurityHandler_GetWAFExclusions_InvalidJSON
time="2025-12-12T19:05:52Z" level=warning msg="Failed to parse WAF exclusions" error="invalid character 'i' looking for beginning of value"
--- PASS: TestSecurityHandler_GetWAFExclusions_InvalidJSON (0.00s)
=== RUN   TestSecurityHandler_AddWAFExclusion_Success

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_AddWAFExclusion_Success (0.00s)
=== RUN   TestSecurityHandler_AddWAFExclusion_WithTarget

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_AddWAFExclusion_WithTarget (0.00s)
=== RUN   TestSecurityHandler_AddWAFExclusion_ToExistingConfig
--- PASS: TestSecurityHandler_AddWAFExclusion_ToExistingConfig (0.00s)
=== RUN   TestSecurityHandler_AddWAFExclusion_Duplicate
--- PASS: TestSecurityHandler_AddWAFExclusion_Duplicate (0.00s)
=== RUN   TestSecurityHandler_AddWAFExclusion_DuplicateWithDifferentTarget
--- PASS: TestSecurityHandler_AddWAFExclusion_DuplicateWithDifferentTarget (0.00s)
=== RUN   TestSecurityHandler_AddWAFExclusion_MissingRuleID
--- PASS: TestSecurityHandler_AddWAFExclusion_MissingRuleID (0.00s)
=== RUN   TestSecurityHandler_AddWAFExclusion_InvalidRuleID
--- PASS: TestSecurityHandler_AddWAFExclusion_InvalidRuleID (0.00s)
=== RUN   TestSecurityHandler_AddWAFExclusion_NegativeRuleID
--- PASS: TestSecurityHandler_AddWAFExclusion_NegativeRuleID (0.00s)
=== RUN   TestSecurityHandler_AddWAFExclusion_InvalidPayload
--- PASS: TestSecurityHandler_AddWAFExclusion_InvalidPayload (0.00s)
=== RUN   TestSecurityHandler_DeleteWAFExclusion_Success
--- PASS: TestSecurityHandler_DeleteWAFExclusion_Success (0.00s)
=== RUN   TestSecurityHandler_DeleteWAFExclusion_WithTarget
--- PASS: TestSecurityHandler_DeleteWAFExclusion_WithTarget (0.00s)
=== RUN   TestSecurityHandler_DeleteWAFExclusion_NotFound
--- PASS: TestSecurityHandler_DeleteWAFExclusion_NotFound (0.00s)
=== RUN   TestSecurityHandler_DeleteWAFExclusion_NoConfig

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_DeleteWAFExclusion_NoConfig (0.00s)
=== RUN   TestSecurityHandler_DeleteWAFExclusion_InvalidRuleID
--- PASS: TestSecurityHandler_DeleteWAFExclusion_InvalidRuleID (0.00s)
=== RUN   TestSecurityHandler_DeleteWAFExclusion_ZeroRuleID
--- PASS: TestSecurityHandler_DeleteWAFExclusion_ZeroRuleID (0.00s)
=== RUN   TestSecurityHandler_DeleteWAFExclusion_NegativeRuleID
--- PASS: TestSecurityHandler_DeleteWAFExclusion_NegativeRuleID (0.00s)
=== RUN   TestSecurityHandler_WAFExclusion_FullWorkflow

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityHandler_WAFExclusion_FullWorkflow (0.00s)
=== RUN   TestProxyHost_WAFDisabled_DefaultFalse
--- PASS: TestProxyHost_WAFDisabled_DefaultFalse (0.00s)
=== RUN   TestProxyHost_WAFDisabled_SetTrue
--- PASS: TestProxyHost_WAFDisabled_SetTrue (0.00s)
=== RUN   TestSecurityConfig_WAFParanoiaLevel_Default
--- PASS: TestSecurityConfig_WAFParanoiaLevel_Default (0.00s)
=== RUN   TestSecurityConfig_WAFParanoiaLevel_CustomValue
--- PASS: TestSecurityConfig_WAFParanoiaLevel_CustomValue (0.00s)
=== RUN   TestSecurityConfig_WAFExclusions_Empty
--- PASS: TestSecurityConfig_WAFExclusions_Empty (0.00s)
=== RUN   TestSecurityConfig_WAFExclusions_JSONArray
--- PASS: TestSecurityConfig_WAFExclusions_JSONArray (0.00s)
=== RUN   TestSecurityNotificationHandler_GetSettings

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationHandler_GetSettings (0.00s)
=== RUN   TestSecurityNotificationHandler_UpdateSettings

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationHandler_UpdateSettings (0.00s)
=== RUN   TestSecurityNotificationHandler_InvalidLevel
--- PASS: TestSecurityNotificationHandler_InvalidLevel (0.00s)
=== RUN   TestSecurityNotificationHandler_UpdateSettings_InvalidJSON
--- PASS: TestSecurityNotificationHandler_UpdateSettings_InvalidJSON (0.00s)
=== RUN   TestSecurityNotificationHandler_UpdateSettings_ValidLevels

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationHandler_UpdateSettings_ValidLevels (0.00s)
=== RUN   TestSecurityNotificationHandler_GetSettings_DatabaseError

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1msql: database is closed
[0m[33m[0.004ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationHandler_GetSettings_DatabaseError (0.00s)
=== RUN   TestSecurityNotificationHandler_GetSettings_EmptySettings

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationHandler_GetSettings_EmptySettings (0.00s)
=== RUN   TestSecurityHandler_GetRateLimitPresets
--- PASS: TestSecurityHandler_GetRateLimitPresets (0.00s)
=== RUN   TestSecurityHandler_GetRateLimitPresets_StandardPreset
--- PASS: TestSecurityHandler_GetRateLimitPresets_StandardPreset (0.00s)
=== RUN   TestSecurityHandler_GetRateLimitPresets_LoginPreset
--- PASS: TestSecurityHandler_GetRateLimitPresets_LoginPreset (0.00s)
=== RUN   TestGetClientIPHeadersAndRemoteAddr
--- PASS: TestGetClientIPHeadersAndRemoteAddr (0.00s)
=== RUN   TestGetMyIPHandler
=== RUN   TestGetMyIPHandler/with_CF_header
=== RUN   TestGetMyIPHandler/with_X-Forwarded-For_header
=== RUN   TestGetMyIPHandler/with_X-Real-IP_header
=== RUN   TestGetMyIPHandler/direct_connection
--- PASS: TestGetMyIPHandler (0.00s)
    --- PASS: TestGetMyIPHandler/with_CF_header (0.00s)
    --- PASS: TestGetMyIPHandler/with_X-Forwarded-For_header (0.00s)
    --- PASS: TestGetMyIPHandler/with_X-Real-IP_header (0.00s)
    --- PASS: TestGetMyIPHandler/direct_connection (0.00s)
=== RUN   TestUpdateHandler_Check
--- PASS: TestUpdateHandler_Check (0.00s)
=== RUN   TestUserHandler_GetSetupStatus_Error

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:55 [35;1mno such table: users
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT count(*) FROM `users`
--- PASS: TestUserHandler_GetSetupStatus_Error (0.00s)
=== RUN   TestUserHandler_Setup_CheckStatusError

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:75 [35;1mno such table: users
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT count(*) FROM `users`
--- PASS: TestUserHandler_Setup_CheckStatusError (0.00s)
=== RUN   TestUserHandler_Setup_AlreadyCompleted
--- PASS: TestUserHandler_Setup_AlreadyCompleted (0.06s)
=== RUN   TestUserHandler_Setup_InvalidJSON
--- PASS: TestUserHandler_Setup_InvalidJSON (0.00s)
=== RUN   TestUserHandler_RegenerateAPIKey_Unauthorized
--- PASS: TestUserHandler_RegenerateAPIKey_Unauthorized (0.00s)
=== RUN   TestUserHandler_RegenerateAPIKey_DBError

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:152 [35;1mno such table: users
[0m[33m[0.056ms] [34;1m[rows:0][0m UPDATE `users` SET `api_key`="b8c75043-8fe9-4819-acaa-a65bc2a5d020",`updated_at`="2025-12-12 19:05:52.585" WHERE id = 1
--- PASS: TestUserHandler_RegenerateAPIKey_DBError (0.00s)
=== RUN   TestUserHandler_GetProfile_Unauthorized
--- PASS: TestUserHandler_GetProfile_Unauthorized (0.00s)
=== RUN   TestUserHandler_GetProfile_NotFound

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:169 [35;1mrecord not found
[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 9999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_GetProfile_NotFound (0.00s)
=== RUN   TestUserHandler_UpdateProfile_Unauthorized
--- PASS: TestUserHandler_UpdateProfile_Unauthorized (0.00s)
=== RUN   TestUserHandler_UpdateProfile_InvalidJSON
--- PASS: TestUserHandler_UpdateProfile_InvalidJSON (0.00s)
=== RUN   TestUserHandler_UpdateProfile_UserNotFound

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:205 [35;1mrecord not found
[0m[33m[0.043ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 9999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_UpdateProfile_UserNotFound (0.00s)
=== RUN   TestUserHandler_UpdateProfile_EmailConflict
--- PASS: TestUserHandler_UpdateProfile_EmailConflict (0.12s)
=== RUN   TestUserHandler_UpdateProfile_EmailChangeNoPassword
--- PASS: TestUserHandler_UpdateProfile_EmailChangeNoPassword (0.06s)
=== RUN   TestUserHandler_UpdateProfile_WrongPassword
--- PASS: TestUserHandler_UpdateProfile_WrongPassword (0.12s)
=== RUN   TestUserHandler_GetSetupStatus
--- PASS: TestUserHandler_GetSetupStatus (0.00s)
=== RUN   TestUserHandler_Setup
--- PASS: TestUserHandler_Setup (0.06s)
=== RUN   TestUserHandler_Setup_DBError
--- PASS: TestUserHandler_Setup_DBError (0.00s)
=== RUN   TestUserHandler_RegenerateAPIKey
--- PASS: TestUserHandler_RegenerateAPIKey (0.00s)
=== RUN   TestUserHandler_GetProfile
--- PASS: TestUserHandler_GetProfile (0.00s)
=== RUN   TestUserHandler_RegisterRoutes
--- PASS: TestUserHandler_RegisterRoutes (0.00s)
=== RUN   TestUserHandler_Errors

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:169 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 99999 ORDER BY `users`.`id` LIMIT 1

2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:152 [35;1mno such table: users
[0m[33m[0.048ms] [34;1m[rows:0][0m UPDATE `users` SET `api_key`="5ecabc02-1821-4ec6-bd8c-1b217bc10aa4",`updated_at`="2025-12-12 19:05:52.978" WHERE id = 99999
--- PASS: TestUserHandler_Errors (0.00s)
=== RUN   TestUserHandler_UpdateProfile
=== RUN   TestUserHandler_UpdateProfile/Success_Name_Only
=== RUN   TestUserHandler_UpdateProfile/Success_Email_Change
=== RUN   TestUserHandler_UpdateProfile/Fail_Email_Change_No_Password
=== RUN   TestUserHandler_UpdateProfile/Fail_Email_Change_Wrong_Password
=== RUN   TestUserHandler_UpdateProfile/Fail_Email_In_Use
--- PASS: TestUserHandler_UpdateProfile (0.19s)
    --- PASS: TestUserHandler_UpdateProfile/Success_Name_Only (0.00s)
    --- PASS: TestUserHandler_UpdateProfile/Success_Email_Change (0.06s)
    --- PASS: TestUserHandler_UpdateProfile/Fail_Email_Change_No_Password (0.00s)
    --- PASS: TestUserHandler_UpdateProfile/Fail_Email_Change_Wrong_Password (0.06s)
    --- PASS: TestUserHandler_UpdateProfile/Fail_Email_In_Use (0.00s)
=== RUN   TestUserHandler_UpdateProfile_Errors

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:205 [35;1mrecord not found
[0m[33m[0.040ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_UpdateProfile_Errors (0.00s)
=== RUN   TestUserHandler_ListUsers_NonAdmin
--- PASS: TestUserHandler_ListUsers_NonAdmin (0.00s)
=== RUN   TestUserHandler_ListUsers_Admin
--- PASS: TestUserHandler_ListUsers_Admin (0.00s)
=== RUN   TestUserHandler_CreateUser_NonAdmin
--- PASS: TestUserHandler_CreateUser_NonAdmin (0.00s)
=== RUN   TestUserHandler_CreateUser_Admin
--- PASS: TestUserHandler_CreateUser_Admin (0.07s)
=== RUN   TestUserHandler_CreateUser_InvalidJSON
--- PASS: TestUserHandler_CreateUser_InvalidJSON (0.00s)
=== RUN   TestUserHandler_CreateUser_DuplicateEmail
--- PASS: TestUserHandler_CreateUser_DuplicateEmail (0.00s)
=== RUN   TestUserHandler_CreateUser_WithPermittedHosts
--- PASS: TestUserHandler_CreateUser_WithPermittedHosts (0.06s)
=== RUN   TestUserHandler_GetUser_NonAdmin
--- PASS: TestUserHandler_GetUser_NonAdmin (0.00s)
=== RUN   TestUserHandler_GetUser_InvalidID
--- PASS: TestUserHandler_GetUser_InvalidID (0.00s)
=== RUN   TestUserHandler_GetUser_NotFound

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:540 [35;1mrecord not found
[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_GetUser_NotFound (0.00s)
=== RUN   TestUserHandler_GetUser_Success
--- PASS: TestUserHandler_GetUser_Success (0.00s)
=== RUN   TestUserHandler_UpdateUser_NonAdmin
--- PASS: TestUserHandler_UpdateUser_NonAdmin (0.00s)
=== RUN   TestUserHandler_UpdateUser_InvalidID
--- PASS: TestUserHandler_UpdateUser_InvalidID (0.00s)
=== RUN   TestUserHandler_UpdateUser_InvalidJSON
--- PASS: TestUserHandler_UpdateUser_InvalidJSON (0.00s)
=== RUN   TestUserHandler_UpdateUser_NotFound

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:592 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_UpdateUser_NotFound (0.00s)
=== RUN   TestUserHandler_UpdateUser_Success
--- PASS: TestUserHandler_UpdateUser_Success (0.00s)
=== RUN   TestUserHandler_DeleteUser_NonAdmin
--- PASS: TestUserHandler_DeleteUser_NonAdmin (0.00s)
=== RUN   TestUserHandler_DeleteUser_InvalidID
--- PASS: TestUserHandler_DeleteUser_InvalidID (0.00s)
=== RUN   TestUserHandler_DeleteUser_NotFound

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:662 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_DeleteUser_NotFound (0.00s)
=== RUN   TestUserHandler_DeleteUser_Success
--- PASS: TestUserHandler_DeleteUser_Success (0.00s)
=== RUN   TestUserHandler_DeleteUser_CannotDeleteSelf
--- PASS: TestUserHandler_DeleteUser_CannotDeleteSelf (0.00s)
=== RUN   TestUserHandler_UpdateUserPermissions_NonAdmin
--- PASS: TestUserHandler_UpdateUserPermissions_NonAdmin (0.00s)
=== RUN   TestUserHandler_UpdateUserPermissions_InvalidID
--- PASS: TestUserHandler_UpdateUserPermissions_InvalidID (0.00s)
=== RUN   TestUserHandler_UpdateUserPermissions_InvalidJSON
--- PASS: TestUserHandler_UpdateUserPermissions_InvalidJSON (0.00s)
=== RUN   TestUserHandler_UpdateUserPermissions_NotFound

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:703 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_UpdateUserPermissions_NotFound (0.00s)
=== RUN   TestUserHandler_UpdateUserPermissions_Success
--- PASS: TestUserHandler_UpdateUserPermissions_Success (0.00s)
=== RUN   TestUserHandler_ValidateInvite_MissingToken
--- PASS: TestUserHandler_ValidateInvite_MissingToken (0.00s)
=== RUN   TestUserHandler_ValidateInvite_InvalidToken

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:752 [35;1mrecord not found
[0m[33m[0.035ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE invite_token = "invalidtoken" ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_ValidateInvite_InvalidToken (0.00s)
=== RUN   TestUserHandler_ValidateInvite_ExpiredToken
--- PASS: TestUserHandler_ValidateInvite_ExpiredToken (0.00s)
=== RUN   TestUserHandler_ValidateInvite_AlreadyAccepted
--- PASS: TestUserHandler_ValidateInvite_AlreadyAccepted (0.00s)
=== RUN   TestUserHandler_ValidateInvite_Success
--- PASS: TestUserHandler_ValidateInvite_Success (0.00s)
=== RUN   TestUserHandler_AcceptInvite_InvalidJSON
--- PASS: TestUserHandler_AcceptInvite_InvalidJSON (0.00s)
=== RUN   TestUserHandler_AcceptInvite_InvalidToken

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:791 [35;1mrecord not found
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE invite_token = "invalidtoken" ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_AcceptInvite_InvalidToken (0.00s)
=== RUN   TestUserHandler_AcceptInvite_Success
--- PASS: TestUserHandler_AcceptInvite_Success (0.06s)
=== RUN   TestGenerateSecureToken
--- PASS: TestGenerateSecureToken (0.00s)
=== RUN   TestUserHandler_InviteUser_NonAdmin
--- PASS: TestUserHandler_InviteUser_NonAdmin (0.00s)
=== RUN   TestUserHandler_InviteUser_InvalidJSON
--- PASS: TestUserHandler_InviteUser_InvalidJSON (0.00s)
=== RUN   TestUserHandler_InviteUser_DuplicateEmail
--- PASS: TestUserHandler_InviteUser_DuplicateEmail (0.00s)
=== RUN   TestUserHandler_InviteUser_Success

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:420 [35;1mrecord not found
[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE email = "newinvite@example.com" ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_InviteUser_Success (0.00s)
=== RUN   TestUserHandler_InviteUser_WithPermittedHosts

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:420 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE email = "invitee-perms@example.com" ORDER BY `users`.`id` LIMIT 1
--- PASS: TestUserHandler_InviteUser_WithPermittedHosts (0.00s)
=== RUN   TestGetBaseURL
--- PASS: TestGetBaseURL (0.00s)
=== RUN   TestGetAppName

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:518 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "app_name" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestGetAppName (0.00s)
=== RUN   TestUserHandler_AcceptInvite_ExpiredToken
--- PASS: TestUserHandler_AcceptInvite_ExpiredToken (0.00s)
=== RUN   TestUserHandler_AcceptInvite_AlreadyAccepted
--- PASS: TestUserHandler_AcceptInvite_AlreadyAccepted (0.00s)
=== RUN   TestUserLoginAfterEmailChange
--- PASS: TestUserLoginAfterEmailChange (0.30s)
=== RUN   TestRemoteServerHandler_List
--- PASS: TestRemoteServerHandler_List (0.00s)
=== RUN   TestRemoteServerHandler_Create
--- PASS: TestRemoteServerHandler_Create (0.00s)
=== RUN   TestRemoteServerHandler_TestConnection
--- PASS: TestRemoteServerHandler_TestConnection (0.00s)
=== RUN   TestRemoteServerHandler_Get
--- PASS: TestRemoteServerHandler_Get (0.00s)
=== RUN   TestRemoteServerHandler_Update
--- PASS: TestRemoteServerHandler_Update (0.00s)
=== RUN   TestRemoteServerHandler_Delete

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "21ab604b-2f0a-4078-8012-f3165c662e99" ORDER BY `remote_servers`.`id` LIMIT 1
--- PASS: TestRemoteServerHandler_Delete (0.00s)
=== RUN   TestProxyHostHandler_List
--- PASS: TestProxyHostHandler_List (0.00s)
=== RUN   TestProxyHostHandler_Create
--- PASS: TestProxyHostHandler_Create (0.00s)
=== RUN   TestProxyHostHandler_PartialUpdate_DoesNotWipeFields
--- PASS: TestProxyHostHandler_PartialUpdate_DoesNotWipeFields (0.00s)
=== RUN   TestHealthHandler
--- PASS: TestHealthHandler (0.00s)
=== RUN   TestRemoteServerHandler_Errors

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent" ORDER BY `remote_servers`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent" ORDER BY `remote_servers`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent" ORDER BY `remote_servers`.`id` LIMIT 1
--- PASS: TestRemoteServerHandler_Errors (0.00s)
=== RUN   TestImportHandler_GetStatus

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:60 [35;1mrecord not found
[0m[33m[0.093ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:60 [35;1mrecord not found
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:70 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE source_file = "/tmp/TestImportHandler_GetStatus3246735047/001/mounted.caddyfile" AND status = "committed" ORDER BY committed_at DESC,`import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_GetStatus (0.00s)
=== RUN   TestImportHandler_GetPreview

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:122 [35;1mrecord not found
[0m[33m[0.102ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_GetPreview (0.00s)
=== RUN   TestImportHandler_Cancel
--- PASS: TestImportHandler_Cancel (0.00s)
=== RUN   TestImportHandler_Commit
--- PASS: TestImportHandler_Commit (0.00s)
=== RUN   TestImportHandler_Upload
--- PASS: TestImportHandler_Upload (0.00s)
=== RUN   TestImportHandler_GetPreview_WithContent
--- PASS: TestImportHandler_GetPreview_WithContent (0.00s)
=== RUN   TestImportHandler_Commit_Errors

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "non-existent" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_Commit_Errors (0.00s)
=== RUN   TestImportHandler_Cancel_Errors

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:734 [35;1mrecord not found
[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "non-existent" ORDER BY `import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_Cancel_Errors (0.00s)
=== RUN   TestCheckMountedImport
--- PASS: TestCheckMountedImport (0.00s)
=== RUN   TestImportHandler_Upload_Failure
--- PASS: TestImportHandler_Upload_Failure (0.00s)
=== RUN   TestImportHandler_Upload_Conflict
--- PASS: TestImportHandler_Upload_Conflict (0.01s)
=== RUN   TestImportHandler_GetPreview_BackupContent
--- PASS: TestImportHandler_GetPreview_BackupContent (0.00s)
=== RUN   TestImportHandler_RegisterRoutes

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:60 [35;1mrecord not found
[0m[33m[0.092ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_RegisterRoutes (0.00s)
=== RUN   TestImportHandler_GetPreview_TransientMount

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:122 [35;1mrecord not found
[0m[33m[0.148ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:167 [35;1mrecord not found
[0m[33m[0.042ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE source_file = "/tmp/TestImportHandler_GetPreview_TransientMount3464543619/001/mounted.caddyfile" AND status = "committed" ORDER BY committed_at DESC,`import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_GetPreview_TransientMount (0.00s)
=== RUN   TestImportHandler_Commit_TransientUpload

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "06368b2d-5607-4012-9972-7646e877fc61" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_Commit_TransientUpload (0.01s)
=== RUN   TestImportHandler_Commit_TransientMount

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
[0m[33m[0.045ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "00e915f7-0eb9-4b38-9d1a-8bd2d7f138d6" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_Commit_TransientMount (0.01s)
=== RUN   TestImportHandler_Cancel_TransientUpload

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:734 [35;1mrecord not found
[0m[33m[0.071ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "7c49c0f2-9908-4546-8a9c-d3c47c4c9860" ORDER BY `import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_Cancel_TransientUpload (0.01s)
=== RUN   TestImportHandler_Errors

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "non-existent" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:734 [35;1mrecord not found
[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "non-existent" ORDER BY `import_sessions`.`id` LIMIT 1
--- PASS: TestImportHandler_Errors (0.00s)
=== RUN   TestImportHandler_DetectImports
=== RUN   TestImportHandler_DetectImports/no_imports
=== RUN   TestImportHandler_DetectImports/single_import
=== RUN   TestImportHandler_DetectImports/multiple_imports
=== RUN   TestImportHandler_DetectImports/import_with_comment
--- PASS: TestImportHandler_DetectImports (0.00s)
    --- PASS: TestImportHandler_DetectImports/no_imports (0.00s)
    --- PASS: TestImportHandler_DetectImports/single_import (0.00s)
    --- PASS: TestImportHandler_DetectImports/multiple_imports (0.00s)
    --- PASS: TestImportHandler_DetectImports/import_with_comment (0.00s)
=== RUN   TestImportHandler_DetectImports_InvalidJSON
--- PASS: TestImportHandler_DetectImports_InvalidJSON (0.00s)
=== RUN   TestImportHandler_UploadMulti
=== RUN   TestImportHandler_UploadMulti/single_Caddyfile
=== RUN   TestImportHandler_UploadMulti/Caddyfile_with_site_files
=== RUN   TestImportHandler_UploadMulti/missing_Caddyfile
=== RUN   TestImportHandler_UploadMulti/path_traversal_in_filename
=== RUN   TestImportHandler_UploadMulti/empty_file_content
--- PASS: TestImportHandler_UploadMulti (0.01s)
    --- PASS: TestImportHandler_UploadMulti/single_Caddyfile (0.01s)
    --- PASS: TestImportHandler_UploadMulti/Caddyfile_with_site_files (0.00s)
    --- PASS: TestImportHandler_UploadMulti/missing_Caddyfile (0.00s)
    --- PASS: TestImportHandler_UploadMulti/path_traversal_in_filename (0.00s)
    --- PASS: TestImportHandler_UploadMulti/empty_file_content (0.00s)
=== RUN   TestNotificationHandler_List
--- PASS: TestNotificationHandler_List (0.00s)
=== RUN   TestNotificationHandler_MarkAsRead
--- PASS: TestNotificationHandler_MarkAsRead (0.00s)
=== RUN   TestNotificationHandler_MarkAllAsRead
--- PASS: TestNotificationHandler_MarkAllAsRead (0.00s)
=== RUN   TestNotificationHandler_MarkAllAsRead_Error
--- PASS: TestNotificationHandler_MarkAllAsRead_Error (0.00s)
=== RUN   TestNotificationHandler_DBError
--- PASS: TestNotificationHandler_DBError (0.00s)
=== RUN   TestNotificationProviderHandler_CRUD
[GIN] 2025/12/12 - 19:05:53 | 201 |      71.971µs |                 | POST     "/api/v1/notifications/providers"
[GIN] 2025/12/12 - 19:05:53 | 200 |       46.98µs |                 | GET      "/api/v1/notifications/providers"
[GIN] 2025/12/12 - 19:05:53 | 200 |       70.04µs |                 | PUT      "/api/v1/notifications/providers/75de70f2-fff3-42d4-b47a-1fdea69c41aa"
[GIN] 2025/12/12 - 19:05:53 | 200 |       32.96µs |                 | DELETE   "/api/v1/notifications/providers/75de70f2-fff3-42d4-b47a-1fdea69c41aa"
--- PASS: TestNotificationProviderHandler_CRUD (0.00s)
=== RUN   TestNotificationProviderHandler_Templates
[GIN] 2025/12/12 - 19:05:53 | 200 |       10.81µs |                 | GET      "/api/v1/notifications/templates"
--- PASS: TestNotificationProviderHandler_Templates (0.00s)
=== RUN   TestNotificationProviderHandler_Test
[GIN] 2025/12/12 - 19:05:53 | 400 |       80.19µs |                 | POST     "/api/v1/notifications/providers/test"
--- PASS: TestNotificationProviderHandler_Test (0.00s)
=== RUN   TestNotificationProviderHandler_Errors
[GIN] 2025/12/12 - 19:05:53 | 400 |       5.739µs |                 | POST     "/api/v1/notifications/providers"
[GIN] 2025/12/12 - 19:05:53 | 400 |        2.42µs |                 | PUT      "/api/v1/notifications/providers/123"
[GIN] 2025/12/12 - 19:05:53 | 400 |        2.57µs |                 | POST     "/api/v1/notifications/providers/test"
--- PASS: TestNotificationProviderHandler_Errors (0.00s)
=== RUN   TestNotificationProviderHandler_InvalidCustomTemplate_Rejects
[GIN] 2025/12/12 - 19:05:53 | 400 |       35.72µs |                 | POST     "/api/v1/notifications/providers"
[GIN] 2025/12/12 - 19:05:53 | 201 |       66.25µs |                 | POST     "/api/v1/notifications/providers"
[GIN] 2025/12/12 - 19:05:53 | 400 |       16.03µs |                 | PUT      "/api/v1/notifications/providers/a0f9d3bf-98ac-497f-a92f-b6e4ff002230"
--- PASS: TestNotificationProviderHandler_InvalidCustomTemplate_Rejects (0.00s)
=== RUN   TestNotificationProviderHandler_Preview
[GIN] 2025/12/12 - 19:05:53 | 200 |       61.36µs |                 | POST     "/api/v1/notifications/providers/preview"
[GIN] 2025/12/12 - 19:05:53 | 400 |       28.06µs |                 | POST     "/api/v1/notifications/providers/preview"
--- PASS: TestNotificationProviderHandler_Preview (0.00s)
=== RUN   TestRemoteServerHandler_TestConnectionCustom
[GIN] 2025/12/12 - 19:05:53 | 200 |     229.651µs |                 | POST     "/api/v1/remote-servers/test"
--- PASS: TestRemoteServerHandler_TestConnectionCustom (0.00s)
=== RUN   TestRemoteServerHandler_FullCRUD
[GIN] 2025/12/12 - 19:05:53 | 201 |     368.301µs |                 | POST     "/api/v1/remote-servers"
[GIN] 2025/12/12 - 19:05:53 | 200 |       64.74µs |                 | GET      "/api/v1/remote-servers"
[GIN] 2025/12/12 - 19:05:53 | 200 |      56.361µs |                 | GET      "/api/v1/remote-servers/fc00458b-7fd6-4d4e-b956-5d9c9485d12a"
[GIN] 2025/12/12 - 19:05:53 | 200 |      296.59µs |                 | PUT      "/api/v1/remote-servers/fc00458b-7fd6-4d4e-b956-5d9c9485d12a"
[GIN] 2025/12/12 - 19:05:53 | 204 |      144.94µs |                 | DELETE   "/api/v1/remote-servers/fc00458b-7fd6-4d4e-b956-5d9c9485d12a"
[GIN] 2025/12/12 - 19:05:53 | 400 |         5.6µs |                 | POST     "/api/v1/remote-servers"

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.037ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent-uuid" ORDER BY `remote_servers`.`id` LIMIT 1
[GIN] 2025/12/12 - 19:05:53 | 404 |       88.54µs |                 | PUT      "/api/v1/remote-servers/non-existent-uuid"

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent-uuid" ORDER BY `remote_servers`.`id` LIMIT 1
[GIN] 2025/12/12 - 19:05:53 | 404 |       51.22µs |                 | DELETE   "/api/v1/remote-servers/non-existent-uuid"
--- PASS: TestRemoteServerHandler_FullCRUD (0.00s)
=== RUN   TestSettingsHandler_GetSettings
--- PASS: TestSettingsHandler_GetSettings (0.00s)
=== RUN   TestSettingsHandler_UpdateSettings
--- PASS: TestSettingsHandler_UpdateSettings (0.00s)
=== RUN   TestSettingsHandler_Errors
--- PASS: TestSettingsHandler_Errors (0.00s)
=== RUN   TestSettingsHandler_GetSMTPConfig
--- PASS: TestSettingsHandler_GetSMTPConfig (0.00s)
=== RUN   TestSettingsHandler_GetSMTPConfig_Empty
--- PASS: TestSettingsHandler_GetSMTPConfig_Empty (0.00s)
=== RUN   TestSettingsHandler_GetSMTPConfig_DatabaseError

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:46 [35;1msql: database is closed
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE category = "smtp"
--- PASS: TestSettingsHandler_GetSMTPConfig_DatabaseError (0.00s)
=== RUN   TestSettingsHandler_UpdateSMTPConfig_NonAdmin
--- PASS: TestSettingsHandler_UpdateSMTPConfig_NonAdmin (0.00s)
=== RUN   TestSettingsHandler_UpdateSMTPConfig_InvalidJSON
--- PASS: TestSettingsHandler_UpdateSMTPConfig_InvalidJSON (0.00s)
=== RUN   TestSettingsHandler_UpdateSMTPConfig_Success

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_host" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_port" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_username" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_password" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_from_address" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_encryption" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestSettingsHandler_UpdateSMTPConfig_Success (0.00s)
=== RUN   TestSettingsHandler_UpdateSMTPConfig_KeepExistingPassword

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_username" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestSettingsHandler_UpdateSMTPConfig_KeepExistingPassword (0.00s)
=== RUN   TestSettingsHandler_TestSMTPConfig_NonAdmin
--- PASS: TestSettingsHandler_TestSMTPConfig_NonAdmin (0.00s)
=== RUN   TestSettingsHandler_TestSMTPConfig_NotConfigured
--- PASS: TestSettingsHandler_TestSMTPConfig_NotConfigured (0.00s)
=== RUN   TestSettingsHandler_SendTestEmail_NonAdmin
--- PASS: TestSettingsHandler_SendTestEmail_NonAdmin (0.00s)
=== RUN   TestSettingsHandler_SendTestEmail_InvalidJSON
--- PASS: TestSettingsHandler_SendTestEmail_InvalidJSON (0.00s)
=== RUN   TestSettingsHandler_SendTestEmail_NotConfigured
--- PASS: TestSettingsHandler_SendTestEmail_NotConfigured (0.00s)
=== RUN   TestMaskPassword
--- PASS: TestMaskPassword (0.00s)
=== RUN   TestUptimeHandler_List
[GIN] 2025/12/12 - 19:05:53 | 200 |      141.91µs |                 | GET      "/api/v1/uptime"
--- PASS: TestUptimeHandler_List (0.00s)
=== RUN   TestUptimeHandler_GetHistory
[GIN] 2025/12/12 - 19:05:53 | 200 |       85.09µs |                 | GET      "/api/v1/uptime/monitor-1/history"
--- PASS: TestUptimeHandler_GetHistory (0.00s)
=== RUN   TestUptimeHandler_CheckMonitor
[GIN] 2025/12/12 - 19:05:53 | 200 |      54.289µs |                 | POST     "/api/v1/uptime/check-mon-1/check"
--- PASS: TestUptimeHandler_CheckMonitor (0.00s)
=== RUN   TestUptimeHandler_CheckMonitor_NotFound

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:869 [35;1mrecord not found
[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "nonexistent" ORDER BY `uptime_monitors`.`id` LIMIT 1
[GIN] 2025/12/12 - 19:05:53 | 404 |       79.99µs |                 | POST     "/api/v1/uptime/nonexistent/check"
--- PASS: TestUptimeHandler_CheckMonitor_NotFound (0.00s)
=== RUN   TestUptimeHandler_Update
=== RUN   TestUptimeHandler_Update/success
[GIN] 2025/12/12 - 19:05:53 | 200 |     297.212µs |                 | PUT      "/api/v1/uptime/monitor-update"
=== RUN   TestUptimeHandler_Update/invalid_json
[GIN] 2025/12/12 - 19:05:53 | 400 |        6.02µs |                 | PUT      "/api/v1/uptime/monitor-1"
=== RUN   TestUptimeHandler_Update/not_found

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:883 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "nonexistent" ORDER BY `uptime_monitors`.`id` LIMIT 1
[GIN] 2025/12/12 - 19:05:53 | 500 |      71.829µs |                 | PUT      "/api/v1/uptime/nonexistent"
--- PASS: TestUptimeHandler_Update (0.01s)
    --- PASS: TestUptimeHandler_Update/success (0.00s)
    --- PASS: TestUptimeHandler_Update/invalid_json (0.00s)
    --- PASS: TestUptimeHandler_Update/not_found (0.00s)
=== RUN   TestUptimeHandler_DeleteAndSync
=== RUN   TestUptimeHandler_DeleteAndSync/delete_monitor
[GIN] 2025/12/12 - 19:05:53 | 200 |     131.741µs |                 | DELETE   "/api/v1/uptime/mon-delete"

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/uptime_handler_test.go:202 [35;1mrecord not found
[0m[33m[0.042ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "mon-delete" ORDER BY `uptime_monitors`.`id` LIMIT 1
=== RUN   TestUptimeHandler_DeleteAndSync/sync_creates_monitor_for_proxy_host

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "127.0.0.1" ORDER BY `uptime_hosts`.`id` LIMIT 1
[GIN] 2025/12/12 - 19:05:53 | 200 |     405.001µs |                 | POST     "/api/v1/uptime/sync"
=== RUN   TestUptimeHandler_DeleteAndSync/update_enabled_via_PUT
[GIN] 2025/12/12 - 19:05:53 | 200 |     121.051µs |                 | PUT      "/api/v1/uptime/mon-enable"
--- PASS: TestUptimeHandler_DeleteAndSync (0.01s)
    --- PASS: TestUptimeHandler_DeleteAndSync/delete_monitor (0.00s)
    --- PASS: TestUptimeHandler_DeleteAndSync/sync_creates_monitor_for_proxy_host (0.00s)
    --- PASS: TestUptimeHandler_DeleteAndSync/update_enabled_via_PUT (0.00s)
=== RUN   TestUptimeHandler_Sync_Success
[GIN] 2025/12/12 - 19:05:53 | 200 |        63.5µs |                 | POST     "/api/v1/uptime/sync"
--- PASS: TestUptimeHandler_Sync_Success (0.00s)
=== RUN   TestUptimeHandler_Delete_Error

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:911 [35;1mno such table: uptime_monitors
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "nonexistent" ORDER BY `uptime_monitors`.`id` LIMIT 1
[GIN] 2025/12/12 - 19:05:53 | 500 |      53.249µs |                 | DELETE   "/api/v1/uptime/nonexistent"
--- PASS: TestUptimeHandler_Delete_Error (0.00s)
=== RUN   TestUptimeHandler_List_Error

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:863 [35;1mno such table: uptime_monitors
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` ORDER BY name ASC
[GIN] 2025/12/12 - 19:05:53 | 500 |       50.51µs |                 | GET      "/api/v1/uptime"
--- PASS: TestUptimeHandler_List_Error (0.00s)
=== RUN   TestUptimeHandler_GetHistory_Error

2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:877 [35;1mno such table: uptime_heartbeats
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `uptime_heartbeats` WHERE monitor_id = "monitor-1" ORDER BY created_at desc LIMIT 50
[GIN] 2025/12/12 - 19:05:53 | 500 |      65.371µs |                 | GET      "/api/v1/uptime/monitor-1/history"
--- PASS: TestUptimeHandler_GetHistory_Error (0.00s)
FAIL
FAIL	github.com/Wikid82/charon/backend/internal/api/handlers	20.305s
=== RUN   TestAuthMiddleware_MissingHeader
--- PASS: TestAuthMiddleware_MissingHeader (0.00s)
=== RUN   TestRequireRole_Success
--- PASS: TestRequireRole_Success (0.00s)
=== RUN   TestRequireRole_Forbidden
--- PASS: TestRequireRole_Forbidden (0.00s)
=== RUN   TestAuthMiddleware_Cookie
--- PASS: TestAuthMiddleware_Cookie (0.07s)
=== RUN   TestAuthMiddleware_ValidToken
--- PASS: TestAuthMiddleware_ValidToken (0.06s)
=== RUN   TestAuthMiddleware_PrefersAuthorizationHeader
--- PASS: TestAuthMiddleware_PrefersAuthorizationHeader (0.06s)
=== RUN   TestAuthMiddleware_InvalidToken
--- PASS: TestAuthMiddleware_InvalidToken (0.00s)
=== RUN   TestRequireRole_MissingRoleInContext
--- PASS: TestRequireRole_MissingRoleInContext (0.00s)
=== RUN   TestRecoveryLogsStacktraceVerbose
--- PASS: TestRecoveryLogsStacktraceVerbose (0.00s)
=== RUN   TestRecoveryLogsBriefWhenNotVerbose
--- PASS: TestRecoveryLogsBriefWhenNotVerbose (0.00s)
=== RUN   TestRecoverySanitizesHeadersAndPath
--- PASS: TestRecoverySanitizesHeadersAndPath (0.00s)
=== RUN   TestRequestIDAddsHeaderAndLogger
--- PASS: TestRequestIDAddsHeaderAndLogger (0.00s)
=== RUN   TestRequestLoggerSanitizesPath
--- PASS: TestRequestLoggerSanitizesPath (0.00s)
=== RUN   TestRequestLoggerIncludesRequestID
--- PASS: TestRequestLoggerIncludesRequestID (0.00s)
=== RUN   TestSanitizeHeaders
=== RUN   TestSanitizeHeaders/nil_headers
=== RUN   TestSanitizeHeaders/redacts_sensitive_headers
=== RUN   TestSanitizeHeaders/sanitizes_and_truncates_values
--- PASS: TestSanitizeHeaders (0.00s)
    --- PASS: TestSanitizeHeaders/nil_headers (0.00s)
    --- PASS: TestSanitizeHeaders/redacts_sensitive_headers (0.00s)
    --- PASS: TestSanitizeHeaders/sanitizes_and_truncates_values (0.00s)
=== RUN   TestSanitizePath
--- PASS: TestSanitizePath (0.00s)
=== RUN   TestSecurityHeaders
=== RUN   TestSecurityHeaders/production_mode_sets_HSTS
=== RUN   TestSecurityHeaders/development_mode_skips_HSTS
=== RUN   TestSecurityHeaders/sets_X-Frame-Options
=== RUN   TestSecurityHeaders/sets_X-Content-Type-Options
=== RUN   TestSecurityHeaders/sets_X-XSS-Protection
=== RUN   TestSecurityHeaders/sets_Referrer-Policy
=== RUN   TestSecurityHeaders/sets_Content-Security-Policy
=== RUN   TestSecurityHeaders/development_mode_CSP_allows_unsafe-eval
=== RUN   TestSecurityHeaders/sets_Permissions-Policy
=== RUN   TestSecurityHeaders/sets_Cross-Origin-Opener-Policy
=== RUN   TestSecurityHeaders/sets_Cross-Origin-Resource-Policy
--- PASS: TestSecurityHeaders (0.00s)
    --- PASS: TestSecurityHeaders/production_mode_sets_HSTS (0.00s)
    --- PASS: TestSecurityHeaders/development_mode_skips_HSTS (0.00s)
    --- PASS: TestSecurityHeaders/sets_X-Frame-Options (0.00s)
    --- PASS: TestSecurityHeaders/sets_X-Content-Type-Options (0.00s)
    --- PASS: TestSecurityHeaders/sets_X-XSS-Protection (0.00s)
    --- PASS: TestSecurityHeaders/sets_Referrer-Policy (0.00s)
    --- PASS: TestSecurityHeaders/sets_Content-Security-Policy (0.00s)
    --- PASS: TestSecurityHeaders/development_mode_CSP_allows_unsafe-eval (0.00s)
    --- PASS: TestSecurityHeaders/sets_Permissions-Policy (0.00s)
    --- PASS: TestSecurityHeaders/sets_Cross-Origin-Opener-Policy (0.00s)
    --- PASS: TestSecurityHeaders/sets_Cross-Origin-Resource-Policy (0.00s)
=== RUN   TestSecurityHeadersCustomCSP
--- PASS: TestSecurityHeadersCustomCSP (0.00s)
=== RUN   TestDefaultSecurityHeadersConfig
--- PASS: TestDefaultSecurityHeadersConfig (0.00s)
=== RUN   TestBuildCSP
=== RUN   TestBuildCSP/production_CSP
=== RUN   TestBuildCSP/development_CSP
--- PASS: TestBuildCSP (0.00s)
    --- PASS: TestBuildCSP/production_CSP (0.00s)
    --- PASS: TestBuildCSP/development_CSP (0.00s)
=== RUN   TestBuildPermissionsPolicy
--- PASS: TestBuildPermissionsPolicy (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/api/middleware	(cached)
=== RUN   TestRegister
time="2025-12-12T19:01:39Z" level=info msg="Cleaning up invalid Let's Encrypt certificate associations..."
time="2025-12-12T19:01:39Z" level=info msg="GeoIP database not found - geo-blocking features will be unavailable" path=/app/data/geoip/GeoLite2-Country.mmdb
time="2025-12-12T19:01:39Z" level=info msg="Using Caddy data directory for certificates scan" caddy_data_dir=/data
--- PASS: TestRegister (0.01s)
=== RUN   TestRegisterImportHandler
--- PASS: TestRegisterImportHandler (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/api/routes	(cached)
=== RUN   TestIntegration_WAF_BlockAndMonitor
time="2025-12-12T19:01:39Z" level=info msg="Cleaning up invalid Let's Encrypt certificate associations..."
time="2025-12-12T19:01:39Z" level=info msg="GeoIP database not found - geo-blocking features will be unavailable" path=/app/data/geoip/GeoLite2-Country.mmdb
time="2025-12-12T19:01:39Z" level=info msg="Using Caddy data directory for certificates scan" caddy_data_dir=data/caddy/data
time="2025-12-12T19:01:39Z" level=info msg="CertificateService: scanning cert directory" certRoot=data/caddy/data/certificates
time="2025-12-12T19:01:39Z" level=info msg="CertificateService: cert directory does not exist" certRoot=data/caddy/data/certificates
time="2025-12-12T19:01:39Z" level=info msg="CertificateService: disk sync complete" count=0
time="2025-12-12T19:01:39Z" level=info msg="Cleaning up invalid Let's Encrypt certificate associations..."
time="2025-12-12T19:01:39Z" level=info msg="GeoIP database not found - geo-blocking features will be unavailable" path=/app/data/geoip/GeoLite2-Country.mmdb
time="2025-12-12T19:01:39Z" level=info msg="Using Caddy data directory for certificates scan" caddy_data_dir=data/caddy/data
time="2025-12-12T19:01:39Z" level=info msg="CertificateService: scanning cert directory" certRoot=data/caddy/data/certificates
time="2025-12-12T19:01:39Z" level=info msg="CertificateService: cert directory does not exist" certRoot=data/caddy/data/certificates
time="2025-12-12T19:01:39Z" level=info msg="CertificateService: disk sync complete" count=0
--- PASS: TestIntegration_WAF_BlockAndMonitor (0.03s)
=== RUN   TestInviteToken_MustBeUnguessable
--- PASS: TestInviteToken_MustBeUnguessable (0.07s)
=== RUN   TestInviteToken_ExpiredCannotBeUsed
--- PASS: TestInviteToken_ExpiredCannotBeUsed (0.06s)
=== RUN   TestInviteToken_CannotBeReused
--- PASS: TestInviteToken_CannotBeReused (0.14s)
=== RUN   TestInviteUser_EmailValidation
=== RUN   TestInviteUser_EmailValidation/empty_email
=== RUN   TestInviteUser_EmailValidation/invalid_email_no_@
=== RUN   TestInviteUser_EmailValidation/invalid_email_no_domain
=== RUN   TestInviteUser_EmailValidation/sql_injection_attempt
=== RUN   TestInviteUser_EmailValidation/script_injection
=== RUN   TestInviteUser_EmailValidation/valid_email
--- PASS: TestInviteUser_EmailValidation (0.13s)
    --- PASS: TestInviteUser_EmailValidation/empty_email (0.00s)
    --- PASS: TestInviteUser_EmailValidation/invalid_email_no_@ (0.00s)
    --- PASS: TestInviteUser_EmailValidation/invalid_email_no_domain (0.00s)
    --- PASS: TestInviteUser_EmailValidation/sql_injection_attempt (0.00s)
    --- PASS: TestInviteUser_EmailValidation/script_injection (0.00s)
    --- PASS: TestInviteUser_EmailValidation/valid_email (0.00s)
=== RUN   TestAcceptInvite_PasswordValidation
=== RUN   TestAcceptInvite_PasswordValidation/empty_password
=== RUN   TestAcceptInvite_PasswordValidation/too_short
=== RUN   TestAcceptInvite_PasswordValidation/7_chars
=== RUN   TestAcceptInvite_PasswordValidation/8_chars_valid
--- PASS: TestAcceptInvite_PasswordValidation (0.19s)
    --- PASS: TestAcceptInvite_PasswordValidation/empty_password (0.00s)
    --- PASS: TestAcceptInvite_PasswordValidation/too_short (0.00s)
    --- PASS: TestAcceptInvite_PasswordValidation/7_chars (0.00s)
    --- PASS: TestAcceptInvite_PasswordValidation/8_chars_valid (0.06s)
=== RUN   TestUserEndpoints_RequireAdmin
=== RUN   TestUserEndpoints_RequireAdmin/GET_/api/users
=== RUN   TestUserEndpoints_RequireAdmin/POST_/api/users
=== RUN   TestUserEndpoints_RequireAdmin/POST_/api/users/invite
=== RUN   TestUserEndpoints_RequireAdmin/GET_/api/users/1
=== RUN   TestUserEndpoints_RequireAdmin/PUT_/api/users/1
=== RUN   TestUserEndpoints_RequireAdmin/DELETE_/api/users/1
=== RUN   TestUserEndpoints_RequireAdmin/PUT_/api/users/1/permissions
--- PASS: TestUserEndpoints_RequireAdmin (0.07s)
    --- PASS: TestUserEndpoints_RequireAdmin/GET_/api/users (0.00s)
    --- PASS: TestUserEndpoints_RequireAdmin/POST_/api/users (0.00s)
    --- PASS: TestUserEndpoints_RequireAdmin/POST_/api/users/invite (0.00s)
    --- PASS: TestUserEndpoints_RequireAdmin/GET_/api/users/1 (0.00s)
    --- PASS: TestUserEndpoints_RequireAdmin/PUT_/api/users/1 (0.00s)
    --- PASS: TestUserEndpoints_RequireAdmin/DELETE_/api/users/1 (0.00s)
    --- PASS: TestUserEndpoints_RequireAdmin/PUT_/api/users/1/permissions (0.00s)
=== RUN   TestSMTPEndpoints_RequireAdmin
=== RUN   TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp
=== RUN   TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp/test
=== RUN   TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp/test-email
--- PASS: TestSMTPEndpoints_RequireAdmin (0.06s)
    --- PASS: TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp (0.00s)
    --- PASS: TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp/test (0.00s)
    --- PASS: TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp/test-email (0.00s)
=== RUN   TestSMTPConfig_PasswordMasked
--- PASS: TestSMTPConfig_PasswordMasked (0.07s)
=== RUN   TestSMTPConfig_PortValidation
=== RUN   TestSMTPConfig_PortValidation/port_0_invalid
=== RUN   TestSMTPConfig_PortValidation/port_-1_invalid
=== RUN   TestSMTPConfig_PortValidation/port_65536_invalid
=== RUN   TestSMTPConfig_PortValidation/port_587_valid
=== RUN   TestSMTPConfig_PortValidation/port_465_valid
=== RUN   TestSMTPConfig_PortValidation/port_25_valid
--- PASS: TestSMTPConfig_PortValidation (0.07s)
    --- PASS: TestSMTPConfig_PortValidation/port_0_invalid (0.00s)
    --- PASS: TestSMTPConfig_PortValidation/port_-1_invalid (0.00s)
    --- PASS: TestSMTPConfig_PortValidation/port_65536_invalid (0.00s)
    --- PASS: TestSMTPConfig_PortValidation/port_587_valid (0.00s)
    --- PASS: TestSMTPConfig_PortValidation/port_465_valid (0.00s)
    --- PASS: TestSMTPConfig_PortValidation/port_25_valid (0.00s)
=== RUN   TestSMTPConfig_EncryptionValidation
=== RUN   TestSMTPConfig_EncryptionValidation/empty_encryption_invalid
=== RUN   TestSMTPConfig_EncryptionValidation/invalid_encryption
=== RUN   TestSMTPConfig_EncryptionValidation/tls_lowercase_valid
=== RUN   TestSMTPConfig_EncryptionValidation/starttls_valid
=== RUN   TestSMTPConfig_EncryptionValidation/none_valid
--- PASS: TestSMTPConfig_EncryptionValidation (0.07s)
    --- PASS: TestSMTPConfig_EncryptionValidation/empty_encryption_invalid (0.00s)
    --- PASS: TestSMTPConfig_EncryptionValidation/invalid_encryption (0.00s)
    --- PASS: TestSMTPConfig_EncryptionValidation/tls_lowercase_valid (0.00s)
    --- PASS: TestSMTPConfig_EncryptionValidation/starttls_valid (0.00s)
    --- PASS: TestSMTPConfig_EncryptionValidation/none_valid (0.00s)
=== RUN   TestInviteUser_DuplicateEmailBlocked
--- PASS: TestInviteUser_DuplicateEmailBlocked (0.07s)
=== RUN   TestInviteUser_EmailCaseInsensitive
--- PASS: TestInviteUser_EmailCaseInsensitive (0.12s)
=== RUN   TestDeleteUser_CannotDeleteSelf
--- PASS: TestDeleteUser_CannotDeleteSelf (0.06s)
=== RUN   TestUpdatePermissions_ValidModes
=== RUN   TestUpdatePermissions_ValidModes/allow_all_valid
=== RUN   TestUpdatePermissions_ValidModes/deny_all_valid
=== RUN   TestUpdatePermissions_ValidModes/invalid_mode
=== RUN   TestUpdatePermissions_ValidModes/empty_mode
--- PASS: TestUpdatePermissions_ValidModes (0.07s)
    --- PASS: TestUpdatePermissions_ValidModes/allow_all_valid (0.00s)
    --- PASS: TestUpdatePermissions_ValidModes/deny_all_valid (0.00s)
    --- PASS: TestUpdatePermissions_ValidModes/invalid_mode (0.00s)
    --- PASS: TestUpdatePermissions_ValidModes/empty_mode (0.00s)
=== RUN   TestPublicEndpoints_NoAuthRequired
--- PASS: TestPublicEndpoints_NoAuthRequired (0.06s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/api/tests	(cached)
=== RUN   TestClient_Load_Success
--- PASS: TestClient_Load_Success (0.00s)
=== RUN   TestClient_Load_Failure
--- PASS: TestClient_Load_Failure (0.00s)
=== RUN   TestClient_GetConfig_Success
--- PASS: TestClient_GetConfig_Success (0.00s)
=== RUN   TestClient_Ping_Success
--- PASS: TestClient_Ping_Success (0.00s)
=== RUN   TestClient_Ping_Unreachable
--- PASS: TestClient_Ping_Unreachable (0.00s)
=== RUN   TestClient_Load_CreateRequestFailure
--- PASS: TestClient_Load_CreateRequestFailure (0.00s)
=== RUN   TestClient_Ping_CreateRequestFailure
--- PASS: TestClient_Ping_CreateRequestFailure (0.00s)
=== RUN   TestClient_GetConfig_Failure
--- PASS: TestClient_GetConfig_Failure (0.00s)
=== RUN   TestClient_GetConfig_InvalidJSON
--- PASS: TestClient_GetConfig_InvalidJSON (0.00s)
=== RUN   TestClient_Ping_Failure
--- PASS: TestClient_Ping_Failure (0.00s)
=== RUN   TestClient_RequestCreationErrors
--- PASS: TestClient_RequestCreationErrors (0.00s)
=== RUN   TestClient_NetworkErrors
--- PASS: TestClient_NetworkErrors (0.00s)
=== RUN   TestClient_Load_MarshalFailure
--- PASS: TestClient_Load_MarshalFailure (0.00s)
=== RUN   TestClient_Ping_TransportError
--- PASS: TestClient_Ping_TransportError (0.00s)
=== RUN   TestBuildACLHandler_GeoBlacklist
--- PASS: TestBuildACLHandler_GeoBlacklist (0.00s)
=== RUN   TestBuildACLHandler_UnknownTypeReturnsNil
--- PASS: TestBuildACLHandler_UnknownTypeReturnsNil (0.00s)
=== RUN   TestBuildACLHandler_GeoWhitelist
--- PASS: TestBuildACLHandler_GeoWhitelist (0.00s)
=== RUN   TestBuildACLHandler_LocalNetwork
--- PASS: TestBuildACLHandler_LocalNetwork (0.00s)
=== RUN   TestBuildACLHandler_IPRules
--- PASS: TestBuildACLHandler_IPRules (0.00s)
=== RUN   TestBuildACLHandler_InvalidIPJSON
--- PASS: TestBuildACLHandler_InvalidIPJSON (0.00s)
=== RUN   TestBuildACLHandler_NoIPRulesReturnsNil
--- PASS: TestBuildACLHandler_NoIPRulesReturnsNil (0.00s)
=== RUN   TestBuildACLHandler_Whitelist
--- PASS: TestBuildACLHandler_Whitelist (0.00s)
=== RUN   TestBuildCrowdSecHandler_Disabled
--- PASS: TestBuildCrowdSecHandler_Disabled (0.00s)
=== RUN   TestBuildCrowdSecHandler_EnabledWithoutConfig
--- PASS: TestBuildCrowdSecHandler_EnabledWithoutConfig (0.00s)
=== RUN   TestBuildCrowdSecHandler_EnabledWithEmptyAPIURL
--- PASS: TestBuildCrowdSecHandler_EnabledWithEmptyAPIURL (0.00s)
=== RUN   TestBuildCrowdSecHandler_EnabledWithCustomAPIURL
--- PASS: TestBuildCrowdSecHandler_EnabledWithCustomAPIURL (0.00s)
=== RUN   TestBuildCrowdSecHandler_JSONFormat
--- PASS: TestBuildCrowdSecHandler_JSONFormat (0.00s)
=== RUN   TestBuildCrowdSecHandler_WithHost
--- PASS: TestBuildCrowdSecHandler_WithHost (0.00s)
=== RUN   TestGenerateConfig_WithCrowdSec
--- PASS: TestGenerateConfig_WithCrowdSec (0.00s)
=== RUN   TestGenerateConfig_CrowdSecDisabled
--- PASS: TestGenerateConfig_CrowdSecDisabled (0.00s)
=== RUN   TestGenerateConfig_CatchAllFrontend
--- PASS: TestGenerateConfig_CatchAllFrontend (0.00s)
=== RUN   TestGenerateConfig_AdvancedInvalidJSON
time="2025-12-12T19:01:40Z" level=warning msg="Failed to parse advanced_config for host" error="invalid character 'i' looking for beginning of object key string" host=adv1
--- PASS: TestGenerateConfig_AdvancedInvalidJSON (0.00s)
=== RUN   TestGenerateConfig_AdvancedArrayHandler
--- PASS: TestGenerateConfig_AdvancedArrayHandler (0.00s)
=== RUN   TestGenerateConfig_LowercaseDomains
--- PASS: TestGenerateConfig_LowercaseDomains (0.00s)
=== RUN   TestGenerateConfig_AdvancedObjectHandler
--- PASS: TestGenerateConfig_AdvancedObjectHandler (0.00s)
=== RUN   TestGenerateConfig_AdvancedHeadersStringToArray
--- PASS: TestGenerateConfig_AdvancedHeadersStringToArray (0.00s)
=== RUN   TestGenerateConfig_ACLWhitelistIncluded
--- PASS: TestGenerateConfig_ACLWhitelistIncluded (0.00s)
=== RUN   TestGenerateConfig_SkipsEmptyDomainEntries
--- PASS: TestGenerateConfig_SkipsEmptyDomainEntries (0.00s)
=== RUN   TestGenerateConfig_AdvancedNoHandlerKey
time="2025-12-12T19:01:40Z" level=warning msg="advanced_config for host is not a handler object" host=adv3
--- PASS: TestGenerateConfig_AdvancedNoHandlerKey (0.00s)
=== RUN   TestGenerateConfig_AdvancedUnexpectedJSONStructure
time="2025-12-12T19:01:40Z" level=warning msg="advanced_config for host has unexpected JSON structure" host=adv4
--- PASS: TestGenerateConfig_AdvancedUnexpectedJSONStructure (0.00s)
=== RUN   TestBuildACLHandler_UnknownIPTypeReturnsNil
--- PASS: TestBuildACLHandler_UnknownIPTypeReturnsNil (0.00s)
=== RUN   TestGenerateConfig_SecurityPipeline_Order
--- PASS: TestGenerateConfig_SecurityPipeline_Order (0.00s)
=== RUN   TestGenerateConfig_SecurityPipeline_OmitWhenDisabled
--- PASS: TestGenerateConfig_SecurityPipeline_OmitWhenDisabled (0.00s)
=== RUN   TestGenerateConfig_ZerosslAndBothProviders
--- PASS: TestGenerateConfig_ZerosslAndBothProviders (0.00s)
=== RUN   TestGenerateConfig_SecurityPipeline_Order_Locations
--- PASS: TestGenerateConfig_SecurityPipeline_Order_Locations (0.00s)
=== RUN   TestGenerateConfig_ACLLogWarning
--- PASS: TestGenerateConfig_ACLLogWarning (0.00s)
=== RUN   TestGenerateConfig_ACLHandlerIncluded
--- PASS: TestGenerateConfig_ACLHandlerIncluded (0.00s)
=== RUN   TestGenerateConfig_DecisionsBlockWithAdminExclusion
    config_generate_additional_test.go:147: handles: [
          {
            "handler": "subroute",
            "routes": [
              {
                "handle": [
                  {
                    "body": "Access denied: Blocked by security decision",
                    "handler": "static_response",
                    "status_code": 403
                  }
                ],
                "match": [
                  {
                    "remote_ip": {
                      "ranges": [
                        "1.2.3.4"
                      ]
                    }
                  },
                  {
                    "not": [
                      {
                        "remote_ip": {
                          "ranges": [
                            "10.0.0.1/32"
                          ]
                        }
                      }
                    ]
                  }
                ],
                "terminal": true
              }
            ]
          },
          {
            "flush_interval": -1,
            "handler": "reverse_proxy",
            "upstreams": [
              {
                "dial": "app:8080"
              }
            ]
          }
        ]
--- PASS: TestGenerateConfig_DecisionsBlockWithAdminExclusion (0.00s)
=== RUN   TestGenerateConfig_WAFModeAndRulesetReference
--- PASS: TestGenerateConfig_WAFModeAndRulesetReference (0.00s)
=== RUN   TestGenerateConfig_WAFModeDisabledSkipsHandler
--- PASS: TestGenerateConfig_WAFModeDisabledSkipsHandler (0.00s)
=== RUN   TestGenerateConfig_WAFSelectedSetsContentAndMode
--- PASS: TestGenerateConfig_WAFSelectedSetsContentAndMode (0.00s)
=== RUN   TestGenerateConfig_DecisionAdminPartsEmpty
--- PASS: TestGenerateConfig_DecisionAdminPartsEmpty (0.00s)
=== RUN   TestNormalizeHeaderOps_PreserveStringArray
--- PASS: TestNormalizeHeaderOps_PreserveStringArray (0.00s)
=== RUN   TestGenerateConfig_WAFUsesRuleSet
--- PASS: TestGenerateConfig_WAFUsesRuleSet (0.00s)
=== RUN   TestGenerateConfig_WAFUsesRuleSetFromAdvancedConfig
--- PASS: TestGenerateConfig_WAFUsesRuleSetFromAdvancedConfig (0.00s)
=== RUN   TestGenerateConfig_WAFUsesRuleSetFromAdvancedConfig_Array
--- PASS: TestGenerateConfig_WAFUsesRuleSetFromAdvancedConfig_Array (0.00s)
=== RUN   TestGenerateConfig_WAFUsesRulesetFromSecCfgFallback
--- PASS: TestGenerateConfig_WAFUsesRulesetFromSecCfgFallback (0.00s)
=== RUN   TestGenerateConfig_RateLimitFromSecCfg
--- PASS: TestGenerateConfig_RateLimitFromSecCfg (0.00s)
=== RUN   TestGenerateConfig_CrowdSecHandlerFromSecCfg
--- PASS: TestGenerateConfig_CrowdSecHandlerFromSecCfg (0.00s)
=== RUN   TestGenerateConfig_EmptyHostsAndNoFrontend
--- PASS: TestGenerateConfig_EmptyHostsAndNoFrontend (0.00s)
=== RUN   TestGenerateConfig_SkipsInvalidCustomCert
--- PASS: TestGenerateConfig_SkipsInvalidCustomCert (0.00s)
=== RUN   TestGenerateConfig_SkipsDuplicateDomains
--- PASS: TestGenerateConfig_SkipsDuplicateDomains (0.00s)
=== RUN   TestGenerateConfig_LoadPEMSetsTLSWhenNoACME
--- PASS: TestGenerateConfig_LoadPEMSetsTLSWhenNoACME (0.00s)
=== RUN   TestGenerateConfig_DefaultAcmeStaging
--- PASS: TestGenerateConfig_DefaultAcmeStaging (0.00s)
=== RUN   TestGenerateConfig_ACLHandlerBuildError
--- PASS: TestGenerateConfig_ACLHandlerBuildError (0.00s)
=== RUN   TestGenerateConfig_SkipHostDomainEmptyAndDisabled
--- PASS: TestGenerateConfig_SkipHostDomainEmptyAndDisabled (0.00s)
=== RUN   TestGenerateConfig_CustomCertsAndTLS
--- PASS: TestGenerateConfig_CustomCertsAndTLS (0.00s)
=== RUN   TestGenerateConfig_Empty
--- PASS: TestGenerateConfig_Empty (0.00s)
=== RUN   TestGenerateConfig_SingleHost
--- PASS: TestGenerateConfig_SingleHost (0.00s)
=== RUN   TestGenerateConfig_MultipleHosts
--- PASS: TestGenerateConfig_MultipleHosts (0.00s)
=== RUN   TestGenerateConfig_WebSocketEnabled
--- PASS: TestGenerateConfig_WebSocketEnabled (0.00s)
=== RUN   TestGenerateConfig_EmptyDomain
--- PASS: TestGenerateConfig_EmptyDomain (0.00s)
=== RUN   TestGenerateConfig_Logging
--- PASS: TestGenerateConfig_Logging (0.00s)
=== RUN   TestGenerateConfig_IPHostsSkipAutoHTTPS
--- PASS: TestGenerateConfig_IPHostsSkipAutoHTTPS (0.00s)
=== RUN   TestGenerateConfig_Advanced
--- PASS: TestGenerateConfig_Advanced (0.00s)
=== RUN   TestGenerateConfig_ACMEStaging
--- PASS: TestGenerateConfig_ACMEStaging (0.00s)
=== RUN   TestBuildACLHandler_WhitelistAndBlacklistAdminMerge
--- PASS: TestBuildACLHandler_WhitelistAndBlacklistAdminMerge (0.00s)
=== RUN   TestBuildACLHandler_GeoAndLocalNetwork
--- PASS: TestBuildACLHandler_GeoAndLocalNetwork (0.00s)
=== RUN   TestBuildACLHandler_AdminWhitelistParsing
--- PASS: TestBuildACLHandler_AdminWhitelistParsing (0.00s)
=== RUN   TestBuildRateLimitHandler_Disabled
--- PASS: TestBuildRateLimitHandler_Disabled (0.00s)
=== RUN   TestBuildRateLimitHandler_InvalidValues
--- PASS: TestBuildRateLimitHandler_InvalidValues (0.00s)
=== RUN   TestBuildRateLimitHandler_ValidConfig
--- PASS: TestBuildRateLimitHandler_ValidConfig (0.00s)
=== RUN   TestBuildRateLimitHandler_JSONFormat
--- PASS: TestBuildRateLimitHandler_JSONFormat (0.00s)
=== RUN   TestGenerateConfig_WithRateLimiting
--- PASS: TestGenerateConfig_WithRateLimiting (0.00s)
=== RUN   TestBuildRateLimitHandler_UsesBurst
--- PASS: TestBuildRateLimitHandler_UsesBurst (0.00s)
=== RUN   TestBuildRateLimitHandler_DefaultBurst
--- PASS: TestBuildRateLimitHandler_DefaultBurst (0.00s)
=== RUN   TestBuildRateLimitHandler_BypassList
--- PASS: TestBuildRateLimitHandler_BypassList (0.00s)
=== RUN   TestBuildRateLimitHandler_BypassList_PlainIPs
--- PASS: TestBuildRateLimitHandler_BypassList_PlainIPs (0.00s)
=== RUN   TestBuildRateLimitHandler_BypassList_InvalidEntries
--- PASS: TestBuildRateLimitHandler_BypassList_InvalidEntries (0.00s)
=== RUN   TestBuildRateLimitHandler_BypassList_Empty
--- PASS: TestBuildRateLimitHandler_BypassList_Empty (0.00s)
=== RUN   TestBuildRateLimitHandler_BypassList_AllInvalid
--- PASS: TestBuildRateLimitHandler_BypassList_AllInvalid (0.00s)
=== RUN   TestParseBypassCIDRs
=== RUN   TestParseBypassCIDRs/empty
=== RUN   TestParseBypassCIDRs/single_cidr
=== RUN   TestParseBypassCIDRs/multiple_cidrs
=== RUN   TestParseBypassCIDRs/plain_ipv4
=== RUN   TestParseBypassCIDRs/plain_ipv6
=== RUN   TestParseBypassCIDRs/mixed
=== RUN   TestParseBypassCIDRs/with_spaces
=== RUN   TestParseBypassCIDRs/all_invalid
--- PASS: TestParseBypassCIDRs (0.00s)
    --- PASS: TestParseBypassCIDRs/empty (0.00s)
    --- PASS: TestParseBypassCIDRs/single_cidr (0.00s)
    --- PASS: TestParseBypassCIDRs/multiple_cidrs (0.00s)
    --- PASS: TestParseBypassCIDRs/plain_ipv4 (0.00s)
    --- PASS: TestParseBypassCIDRs/plain_ipv6 (0.00s)
    --- PASS: TestParseBypassCIDRs/mixed (0.00s)
    --- PASS: TestParseBypassCIDRs/with_spaces (0.00s)
    --- PASS: TestParseBypassCIDRs/all_invalid (0.00s)
=== RUN   TestBuildWAFHandler_ParanoiaLevel
=== RUN   TestBuildWAFHandler_ParanoiaLevel/level_1_default
=== RUN   TestBuildWAFHandler_ParanoiaLevel/level_1_explicit
=== RUN   TestBuildWAFHandler_ParanoiaLevel/level_2
=== RUN   TestBuildWAFHandler_ParanoiaLevel/level_3
=== RUN   TestBuildWAFHandler_ParanoiaLevel/level_4_max
=== RUN   TestBuildWAFHandler_ParanoiaLevel/level_invalid_high
=== RUN   TestBuildWAFHandler_ParanoiaLevel/level_invalid_neg
--- PASS: TestBuildWAFHandler_ParanoiaLevel (0.00s)
    --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_1_default (0.00s)
    --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_1_explicit (0.00s)
    --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_2 (0.00s)
    --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_3 (0.00s)
    --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_4_max (0.00s)
    --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_invalid_high (0.00s)
    --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_invalid_neg (0.00s)
=== RUN   TestBuildWAFHandler_Exclusions
--- PASS: TestBuildWAFHandler_Exclusions (0.00s)
=== RUN   TestBuildWAFHandler_ExclusionsWithTarget
--- PASS: TestBuildWAFHandler_ExclusionsWithTarget (0.00s)
=== RUN   TestBuildWAFHandler_PerHostDisabled
--- PASS: TestBuildWAFHandler_PerHostDisabled (0.00s)
=== RUN   TestBuildWAFHandler_MonitorMode
--- PASS: TestBuildWAFHandler_MonitorMode (0.00s)
=== RUN   TestBuildWAFHandler_GlobalDisabled
--- PASS: TestBuildWAFHandler_GlobalDisabled (0.00s)
=== RUN   TestBuildWAFHandler_NoRuleset
--- PASS: TestBuildWAFHandler_NoRuleset (0.00s)
=== RUN   TestParseWAFExclusions
=== RUN   TestParseWAFExclusions/empty
=== RUN   TestParseWAFExclusions/single_exclusion
=== RUN   TestParseWAFExclusions/multiple_exclusions
=== RUN   TestParseWAFExclusions/invalid_json
--- PASS: TestParseWAFExclusions (0.00s)
    --- PASS: TestParseWAFExclusions/empty (0.00s)
    --- PASS: TestParseWAFExclusions/single_exclusion (0.00s)
    --- PASS: TestParseWAFExclusions/multiple_exclusions (0.00s)
    --- PASS: TestParseWAFExclusions/invalid_json (0.00s)
=== RUN   TestGenerateConfig_WithWAFPerHostDisabled
--- PASS: TestGenerateConfig_WithWAFPerHostDisabled (0.00s)
=== RUN   TestBuildWAFHandler_PathTraversalAttack
=== RUN   TestBuildWAFHandler_PathTraversalAttack/Path_traversal_in_ruleset_name
=== RUN   TestBuildWAFHandler_PathTraversalAttack/Null_byte_injection
=== RUN   TestBuildWAFHandler_PathTraversalAttack/URL_encoded_traversal
--- PASS: TestBuildWAFHandler_PathTraversalAttack (0.00s)
    --- PASS: TestBuildWAFHandler_PathTraversalAttack/Path_traversal_in_ruleset_name (0.00s)
    --- PASS: TestBuildWAFHandler_PathTraversalAttack/Null_byte_injection (0.00s)
    --- PASS: TestBuildWAFHandler_PathTraversalAttack/URL_encoded_traversal (0.00s)
=== RUN   TestBuildWAFHandler_SQLInjectionInRulesetName
=== RUN   TestBuildWAFHandler_SQLInjectionInRulesetName/';_DROP_TABLE_rulesets;_--
=== RUN   TestBuildWAFHandler_SQLInjectionInRulesetName/1'_OR_'1'='1
=== RUN   TestBuildWAFHandler_SQLInjectionInRulesetName/UNION_SELECT_*_FROM_users--
=== RUN   TestBuildWAFHandler_SQLInjectionInRulesetName/admin'/*
--- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName (0.00s)
    --- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName/';_DROP_TABLE_rulesets;_-- (0.00s)
    --- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName/1'_OR_'1'='1 (0.00s)
    --- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName/UNION_SELECT_*_FROM_users-- (0.00s)
    --- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName/admin'/* (0.00s)
=== RUN   TestBuildWAFHandler_XSSInAdvancedConfig
=== RUN   TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"<script>alert(1)</script>"}
=== RUN   TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"<img_src=x_onerror=alert(1)>"}
=== RUN   TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"javascript:alert(1)"}
=== RUN   TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"<svg/onload=alert(1)>"}
--- PASS: TestBuildWAFHandler_XSSInAdvancedConfig (0.00s)
    --- PASS: TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"<script>alert(1)</script>"} (0.00s)
    --- PASS: TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"<img_src=x_onerror=alert(1)>"} (0.00s)
    --- PASS: TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"javascript:alert(1)"} (0.00s)
    --- PASS: TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"<svg/onload=alert(1)>"} (0.00s)
=== RUN   TestBuildWAFHandler_HugePayload
--- PASS: TestBuildWAFHandler_HugePayload (0.00s)
=== RUN   TestBuildWAFHandler_EmptyAndWhitespaceInputs
=== RUN   TestBuildWAFHandler_EmptyAndWhitespaceInputs/Empty_string_WAFRulesSource
=== RUN   TestBuildWAFHandler_EmptyAndWhitespaceInputs/Whitespace-only_WAFRulesSource
=== RUN   TestBuildWAFHandler_EmptyAndWhitespaceInputs/Tab_and_newline_in_WAFRulesSource
--- PASS: TestBuildWAFHandler_EmptyAndWhitespaceInputs (0.00s)
    --- PASS: TestBuildWAFHandler_EmptyAndWhitespaceInputs/Empty_string_WAFRulesSource (0.00s)
    --- PASS: TestBuildWAFHandler_EmptyAndWhitespaceInputs/Whitespace-only_WAFRulesSource (0.00s)
    --- PASS: TestBuildWAFHandler_EmptyAndWhitespaceInputs/Tab_and_newline_in_WAFRulesSource (0.00s)
=== RUN   TestBuildWAFHandler_ConcurrentRulesetSelection
--- PASS: TestBuildWAFHandler_ConcurrentRulesetSelection (0.00s)
=== RUN   TestBuildWAFHandler_NilSecCfg
--- PASS: TestBuildWAFHandler_NilSecCfg (0.00s)
=== RUN   TestBuildWAFHandler_NilHost
--- PASS: TestBuildWAFHandler_NilHost (0.00s)
=== RUN   TestBuildWAFHandler_SpecialCharactersInRulesetName
=== RUN   TestBuildWAFHandler_SpecialCharactersInRulesetName/ruleset_with_spaces
=== RUN   TestBuildWAFHandler_SpecialCharactersInRulesetName/ruleset/with/slashes
=== RUN   TestBuildWAFHandler_SpecialCharactersInRulesetName/UPPERCASE-RULESET
=== RUN   TestBuildWAFHandler_SpecialCharactersInRulesetName/ruleset_with_underscores
=== RUN   TestBuildWAFHandler_SpecialCharactersInRulesetName/ruleset.with.dots
--- PASS: TestBuildWAFHandler_SpecialCharactersInRulesetName (0.00s)
    --- PASS: TestBuildWAFHandler_SpecialCharactersInRulesetName/ruleset_with_spaces (0.00s)
    --- PASS: TestBuildWAFHandler_SpecialCharactersInRulesetName/ruleset/with/slashes (0.00s)
    --- PASS: TestBuildWAFHandler_SpecialCharactersInRulesetName/UPPERCASE-RULESET (0.00s)
    --- PASS: TestBuildWAFHandler_SpecialCharactersInRulesetName/ruleset_with_underscores (0.00s)
    --- PASS: TestBuildWAFHandler_SpecialCharactersInRulesetName/ruleset.with.dots (0.00s)
=== RUN   TestBuildWAFHandler_RulesetSelectionPriority
=== RUN   TestBuildWAFHandler_RulesetSelectionPriority/WAFRulesSource_takes_priority_over_owasp-crs
=== RUN   TestBuildWAFHandler_RulesetSelectionPriority/hostRulesetName_takes_priority_over_owasp-crs
=== RUN   TestBuildWAFHandler_RulesetSelectionPriority/host.Application_takes_priority_over_owasp-crs
=== RUN   TestBuildWAFHandler_RulesetSelectionPriority/owasp-crs_used_as_fallback_when_no_other_match
=== RUN   TestBuildWAFHandler_RulesetSelectionPriority/WAFRulesSource_takes_priority_over_host.Application_and_owasp-crs
--- PASS: TestBuildWAFHandler_RulesetSelectionPriority (0.00s)
    --- PASS: TestBuildWAFHandler_RulesetSelectionPriority/WAFRulesSource_takes_priority_over_owasp-crs (0.00s)
    --- PASS: TestBuildWAFHandler_RulesetSelectionPriority/hostRulesetName_takes_priority_over_owasp-crs (0.00s)
    --- PASS: TestBuildWAFHandler_RulesetSelectionPriority/host.Application_takes_priority_over_owasp-crs (0.00s)
    --- PASS: TestBuildWAFHandler_RulesetSelectionPriority/owasp-crs_used_as_fallback_when_no_other_match (0.00s)
    --- PASS: TestBuildWAFHandler_RulesetSelectionPriority/WAFRulesSource_takes_priority_over_host.Application_and_owasp-crs (0.00s)
=== RUN   TestBuildWAFHandler_NoDirectivesReturnsNil
=== RUN   TestBuildWAFHandler_NoDirectivesReturnsNil/Empty_rulesets_returns_nil
=== RUN   TestBuildWAFHandler_NoDirectivesReturnsNil/Ruleset_exists_but_no_path_mapping_returns_nil
=== RUN   TestBuildWAFHandler_NoDirectivesReturnsNil/WAFRulesSource_specified_but_not_in_rulesets_or_paths_returns_nil
=== RUN   TestBuildWAFHandler_NoDirectivesReturnsNil/Empty_path_in_rulesetPaths_returns_nil
--- PASS: TestBuildWAFHandler_NoDirectivesReturnsNil (0.00s)
    --- PASS: TestBuildWAFHandler_NoDirectivesReturnsNil/Empty_rulesets_returns_nil (0.00s)
    --- PASS: TestBuildWAFHandler_NoDirectivesReturnsNil/Ruleset_exists_but_no_path_mapping_returns_nil (0.00s)
    --- PASS: TestBuildWAFHandler_NoDirectivesReturnsNil/WAFRulesSource_specified_but_not_in_rulesets_or_paths_returns_nil (0.00s)
    --- PASS: TestBuildWAFHandler_NoDirectivesReturnsNil/Empty_path_in_rulesetPaths_returns_nil (0.00s)
=== RUN   TestBuildWAFHandler_DisabledModes
=== RUN   TestBuildWAFHandler_DisabledModes/wafEnabled_false_returns_nil
=== RUN   TestBuildWAFHandler_DisabledModes/WAFMode_disabled_returns_nil
--- PASS: TestBuildWAFHandler_DisabledModes (0.00s)
    --- PASS: TestBuildWAFHandler_DisabledModes/wafEnabled_false_returns_nil (0.00s)
    --- PASS: TestBuildWAFHandler_DisabledModes/WAFMode_disabled_returns_nil (0.00s)
=== RUN   TestBuildWAFHandler_HandlerStructure
--- PASS: TestBuildWAFHandler_HandlerStructure (0.00s)
=== RUN   TestBuildWAFHandler_AdvancedConfigParsing
=== RUN   TestBuildWAFHandler_AdvancedConfigParsing/Valid_ruleset_name_in_advanced_config
=== RUN   TestBuildWAFHandler_AdvancedConfigParsing/Invalid_JSON_falls_back_to_owasp-crs
=== RUN   TestBuildWAFHandler_AdvancedConfigParsing/Empty_advanced_config_falls_back_to_owasp-crs
=== RUN   TestBuildWAFHandler_AdvancedConfigParsing/Empty_ruleset_name_string_falls_back_to_owasp-crs
=== RUN   TestBuildWAFHandler_AdvancedConfigParsing/Non-string_ruleset_name_falls_back_to_owasp-crs
--- PASS: TestBuildWAFHandler_AdvancedConfigParsing (0.00s)
    --- PASS: TestBuildWAFHandler_AdvancedConfigParsing/Valid_ruleset_name_in_advanced_config (0.00s)
    --- PASS: TestBuildWAFHandler_AdvancedConfigParsing/Invalid_JSON_falls_back_to_owasp-crs (0.00s)
    --- PASS: TestBuildWAFHandler_AdvancedConfigParsing/Empty_advanced_config_falls_back_to_owasp-crs (0.00s)
    --- PASS: TestBuildWAFHandler_AdvancedConfigParsing/Empty_ruleset_name_string_falls_back_to_owasp-crs (0.00s)
    --- PASS: TestBuildWAFHandler_AdvancedConfigParsing/Non-string_ruleset_name_falls_back_to_owasp-crs (0.00s)
=== RUN   TestImporter_ExtractHosts_DialWithoutPortDefaultsTo80
--- PASS: TestImporter_ExtractHosts_DialWithoutPortDefaultsTo80 (0.00s)
=== RUN   TestImporter_ExtractHosts_DetectsWebsocketFromHeaders
--- PASS: TestImporter_ExtractHosts_DetectsWebsocketFromHeaders (0.00s)
=== RUN   TestImporter_ImportFile_ParseOutputInvalidJSON
--- PASS: TestImporter_ImportFile_ParseOutputInvalidJSON (0.00s)
=== RUN   TestImporter_ImportFile_ExecutorError
--- PASS: TestImporter_ImportFile_ExecutorError (0.00s)
=== RUN   TestImporter_ExtractHosts_TLSConnectionPolicyAndDialWithoutPort
--- PASS: TestImporter_ExtractHosts_TLSConnectionPolicyAndDialWithoutPort (0.00s)
=== RUN   TestExtractHandlers_Subroute_WithUnsupportedSubhandle
--- PASS: TestExtractHandlers_Subroute_WithUnsupportedSubhandle (0.00s)
=== RUN   TestExtractHandlers_Subroute_WithNonMapRoutes
--- PASS: TestExtractHandlers_Subroute_WithNonMapRoutes (0.00s)
=== RUN   TestImporter_ExtractHosts_UpstreamsNonMapAndWarnings
--- PASS: TestImporter_ExtractHosts_UpstreamsNonMapAndWarnings (0.00s)
=== RUN   TestBackupCaddyfile_ReadFailure
--- PASS: TestBackupCaddyfile_ReadFailure (0.00s)
=== RUN   TestExtractHandlers_Subroute_EmptyAndHandleNotArray
--- PASS: TestExtractHandlers_Subroute_EmptyAndHandleNotArray (0.00s)
=== RUN   TestImporter_ExtractHosts_ReverseProxyNoUpstreams
--- PASS: TestImporter_ExtractHosts_ReverseProxyNoUpstreams (0.00s)
=== RUN   TestBackupCaddyfile_Success
--- PASS: TestBackupCaddyfile_Success (0.00s)
=== RUN   TestExtractHandlers_Subroute_WithHeadersUpstreams
--- PASS: TestExtractHandlers_Subroute_WithHeadersUpstreams (0.00s)
=== RUN   TestImporter_ExtractHosts_DuplicateHost
--- PASS: TestImporter_ExtractHosts_DuplicateHost (0.00s)
=== RUN   TestBackupCaddyfile_WriteFailure
--- PASS: TestBackupCaddyfile_WriteFailure (0.00s)
=== RUN   TestImporter_ExtractHosts_SSLForcedByDomainScheme
--- PASS: TestImporter_ExtractHosts_SSLForcedByDomainScheme (0.00s)
=== RUN   TestImporter_ExtractHosts_MultipleHostsInMatch
--- PASS: TestImporter_ExtractHosts_MultipleHostsInMatch (0.00s)
=== RUN   TestImporter_ExtractHosts_UpgradeHeaderAsString
--- PASS: TestImporter_ExtractHosts_UpgradeHeaderAsString (0.00s)
=== RUN   TestImporter_ExtractHosts_SscanfFailureOnPort
--- PASS: TestImporter_ExtractHosts_SscanfFailureOnPort (0.00s)
=== RUN   TestImporter_ExtractHosts_PartsSscanfFail
--- PASS: TestImporter_ExtractHosts_PartsSscanfFail (0.00s)
=== RUN   TestImporter_ExtractHosts_PartsEmptyPortField
--- PASS: TestImporter_ExtractHosts_PartsEmptyPortField (0.00s)
=== RUN   TestImporter_ExtractHosts_ForceSplitFallback_PartsNumericPort
--- PASS: TestImporter_ExtractHosts_ForceSplitFallback_PartsNumericPort (0.00s)
=== RUN   TestImporter_ExtractHosts_ForceSplitFallback_PartsSscanfFail
--- PASS: TestImporter_ExtractHosts_ForceSplitFallback_PartsSscanfFail (0.00s)
=== RUN   TestBackupCaddyfile_WriteErrorDeterministic
--- PASS: TestBackupCaddyfile_WriteErrorDeterministic (0.00s)
=== RUN   TestParseCaddyfile_InvalidPath
--- PASS: TestParseCaddyfile_InvalidPath (0.00s)
=== RUN   TestBackupCaddyfile_InvalidOriginalPath
--- PASS: TestBackupCaddyfile_InvalidOriginalPath (0.00s)
=== RUN   TestExtractHandlers_Subroute
--- PASS: TestExtractHandlers_Subroute (0.00s)
=== RUN   TestNewImporter
--- PASS: TestNewImporter (0.00s)
=== RUN   TestImporter_ParseCaddyfile_NotFound
--- PASS: TestImporter_ParseCaddyfile_NotFound (0.00s)
=== RUN   TestImporter_ParseCaddyfile_Success
--- PASS: TestImporter_ParseCaddyfile_Success (0.00s)
=== RUN   TestImporter_ParseCaddyfile_Failure
--- PASS: TestImporter_ParseCaddyfile_Failure (0.00s)
=== RUN   TestImporter_ExtractHosts
--- PASS: TestImporter_ExtractHosts (0.00s)
=== RUN   TestImporter_ImportFile
--- PASS: TestImporter_ImportFile (0.00s)
=== RUN   TestConvertToProxyHosts
--- PASS: TestConvertToProxyHosts (0.00s)
=== RUN   TestImporter_ValidateCaddyBinary
--- PASS: TestImporter_ValidateCaddyBinary (0.00s)
=== RUN   TestBackupCaddyfile
--- PASS: TestBackupCaddyfile (0.00s)
=== RUN   TestDefaultExecutor_Execute
--- PASS: TestDefaultExecutor_Execute (0.00s)
=== RUN   TestManager_ListSnapshots_ReadDirError
--- PASS: TestManager_ListSnapshots_ReadDirError (0.00s)
=== RUN   TestManager_RotateSnapshots_NoOp
--- PASS: TestManager_RotateSnapshots_NoOp (0.00s)
=== RUN   TestManager_Rollback_NoSnapshots
--- PASS: TestManager_Rollback_NoSnapshots (0.00s)
=== RUN   TestManager_Rollback_UnmarshalError
--- PASS: TestManager_Rollback_UnmarshalError (0.00s)
=== RUN   TestManager_Rollback_LoadSnapshotFail
--- PASS: TestManager_Rollback_LoadSnapshotFail (0.00s)
=== RUN   TestManager_SaveSnapshot_WriteError
--- PASS: TestManager_SaveSnapshot_WriteError (0.00s)
=== RUN   TestBackupCaddyfile_MkdirAllFailure
--- PASS: TestBackupCaddyfile_MkdirAllFailure (0.00s)
=== RUN   TestManager_SaveSnapshot_Success
--- PASS: TestManager_SaveSnapshot_Success (0.00s)
=== RUN   TestManager_ApplyConfig_WithSettings

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.136ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.070ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_WithSettings (0.00s)
=== RUN   TestManager_RotateSnapshots_ListDirError
--- PASS: TestManager_RotateSnapshots_ListDirError (0.00s)
=== RUN   TestManager_RotateSnapshots_DeletesOld
--- PASS: TestManager_RotateSnapshots_DeletesOld (0.00s)
=== RUN   TestManager_ApplyConfig_RotateSnapshotsWarning

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.185ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.064ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.128ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_RotateSnapshotsWarning (0.01s)
=== RUN   TestManager_ApplyConfig_LoadFailsAndRollbackFails

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.133ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.074ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.048ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_LoadFailsAndRollbackFails (0.00s)
=== RUN   TestManager_ApplyConfig_SaveSnapshotFails

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.125ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.076ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.074ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_SaveSnapshotFails (0.00s)
=== RUN   TestManager_ApplyConfig_LoadFailsThenRollbackSucceeds

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.141ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.077ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.080ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_LoadFailsThenRollbackSucceeds (0.00s)
=== RUN   TestManager_SaveSnapshot_MarshalError
--- PASS: TestManager_SaveSnapshot_MarshalError (0.00s)
=== RUN   TestManager_RotateSnapshots_DeleteError
--- PASS: TestManager_RotateSnapshots_DeleteError (0.00s)
=== RUN   TestManager_ApplyConfig_GenerateConfigFails

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.142ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.074ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.073ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_GenerateConfigFails (0.00s)
=== RUN   TestManager_ApplyConfig_RejectsWhenCerberusEnabledWithoutAdminWhitelist

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestManager_ApplyConfig_RejectsWhenCerberusEnabledWithoutAdminWhitelist (0.00s)
=== RUN   TestManager_ApplyConfig_ValidateFails

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.140ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.073ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.069ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_ValidateFails (0.00s)
=== RUN   TestManager_Rollback_ReadFileError
--- PASS: TestManager_Rollback_ReadFileError (0.00s)
=== RUN   TestManager_ApplyConfig_RotateSnapshotsWarning_Stderr

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.132ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.071ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.067ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_RotateSnapshotsWarning_Stderr (0.00s)
=== RUN   TestManager_ApplyConfig_PassesAdminWhitelistToGenerateConfig

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.095ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_PassesAdminWhitelistToGenerateConfig (0.00s)
=== RUN   TestManager_ApplyConfig_PassesRuleSetsToGenerateConfig

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.081ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_PassesRuleSetsToGenerateConfig (0.00s)
=== RUN   TestManager_ApplyConfig_IncludesWAFHandlerWithRuleset

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.072ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
    manager_additional_test.go:711: generated config: {"admin":{"listen":"0.0.0.0:2019"},"apps":{"http":{"servers":{"charon_server":{"listen":[":80",":443"],"routes":[{"match":[{"host":["ruleset.example.com"]}],"handle":[{"directives":"SecRuleEngine On\nSecRequestBodyAccess On\nSecResponseBodyAccess Off\nSecAction \"id:900000,phase:1,nolog,pass,t:none,setvar:tx.paranoia_level=1\"\nInclude /tmp/TestManager_ApplyConfig_IncludesWAFHandlerWithRuleset3005272911/001/coraza/rulesets/owasp-crs-05ec1bde.conf\n","handler":"waf"},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","upstreams":[{"dial":"127.0.0.1:8080"}]}],"terminal":true}],"automatic_https":{},"logs":{"default_logger_name":"access_log"}}}}},"logging":{"logs":{"access":{"writer":{"output":"file","filename":"/tmp/TestManager_ApplyConfig_IncludesWAFHandlerWithRuleset3005272911/logs/access.log","roll":true,"roll_size_mb":10,"roll_keep":5,"roll_keep_days":7},"encoder":{"format":"json"},"level":"INFO","include":["http.log.access.access_log"]}}},"storage":{"module":"file_system","root":"/tmp/TestManager_ApplyConfig_IncludesWAFHandlerWithRuleset3005272911/001/data"}}
--- PASS: TestManager_ApplyConfig_IncludesWAFHandlerWithRuleset (0.00s)
=== RUN   TestManager_ApplyConfig_RulesetWriteFileFailure

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.060ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_RulesetWriteFileFailure (0.00s)
=== RUN   TestManager_ApplyConfig_RulesetDirMkdirFailure

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.077ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_RulesetDirMkdirFailure (0.00s)
=== RUN   TestManager_ApplyConfig_ReappliesOnFlagChange

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.106ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.049ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.172ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.065ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.005ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_ReappliesOnFlagChange (0.01s)
=== RUN   TestManager_ApplyConfig_PrependsSecRuleEngineDirectives

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.061ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_PrependsSecRuleEngineDirectives (0.00s)
=== RUN   TestManager_ApplyConfig_DoesNotPrependIfSecRuleEngineExists

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.059ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_DoesNotPrependIfSecRuleEngineExists (0.00s)
=== RUN   TestManager_ApplyConfig_DebugMarshalFailure

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.062ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_DebugMarshalFailure (0.00s)
=== RUN   TestManager_ApplyConfig_WAFModeMonitorUsesDetectionOnly

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.066ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_WAFModeMonitorUsesDetectionOnly (0.00s)
=== RUN   TestManager_ApplyConfig_PerRulesetModeOverride

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.058ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_PerRulesetModeOverride (0.00s)
=== RUN   TestManager_ApplyConfig_RulesetFileCleanup

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.074ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_RulesetFileCleanup (0.00s)
=== RUN   TestManager_ApplyConfig_RulesetCleanupReadDirError

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.057ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_RulesetCleanupReadDirError (0.00s)
=== RUN   TestManager_ApplyConfig_RulesetCleanupRemoveError

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.070ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_RulesetCleanupRemoveError (0.00s)
=== RUN   TestManager_ApplyConfig_WAFModeBlockExplicit

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.076ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_WAFModeBlockExplicit (0.00s)
=== RUN   TestManager_ApplyConfig_RulesetNamePathTraversal

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.060ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_RulesetNamePathTraversal (0.00s)
=== RUN   TestManager_ApplyConfig_SSLProvider_Auto

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.035ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.105ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.062ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.074ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_SSLProvider_Auto (0.00s)
=== RUN   TestManager_ApplyConfig_SSLProvider_LetsEncryptStaging

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.129ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.073ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.067ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_SSLProvider_LetsEncryptStaging (0.01s)
=== RUN   TestManager_ApplyConfig_SSLProvider_LetsEncryptProd

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.124ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.080ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.077ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_SSLProvider_LetsEncryptProd (0.00s)
=== RUN   TestManager_ApplyConfig_SSLProvider_ZeroSSL

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.119ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.079ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.076ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_SSLProvider_ZeroSSL (0.00s)
=== RUN   TestManager_ApplyConfig_SSLProvider_Empty

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.089ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.053ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.046ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_SSLProvider_Empty (0.00s)
=== RUN   TestManager_ApplyConfig_SSLProvider_EmptyWithNoStaging

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.127ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.085ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.078ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_SSLProvider_EmptyWithNoStaging (0.00s)
=== RUN   TestManager_ApplyConfig_SSLProvider_Unknown

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.127ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.093ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.088ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_SSLProvider_Unknown (0.00s)
=== RUN   TestManager_ApplyConfig

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.167ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.086ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.081ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig (0.01s)
=== RUN   TestManager_ApplyConfig_Failure

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.144ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.103ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.085ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_Failure (0.00s)
=== RUN   TestManager_Ping
--- PASS: TestManager_Ping (0.00s)
=== RUN   TestManager_GetCurrentConfig
--- PASS: TestManager_GetCurrentConfig (0.00s)
=== RUN   TestManager_RotateSnapshots

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.199ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.140ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.085ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.079ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_RotateSnapshots (0.00s)
=== RUN   TestManager_Rollback_Success

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.113ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.117ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.058ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.005ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_Rollback_Success (1.11s)
=== RUN   TestManager_ApplyConfig_DBError

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:61 [35;1msql: database is closed
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
--- PASS: TestManager_ApplyConfig_DBError (0.00s)
=== RUN   TestManager_ApplyConfig_ValidationError

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.046ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.149ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.084ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.077ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_ApplyConfig_ValidationError (0.01s)
=== RUN   TestManager_Rollback_Failure

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.121ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
[0m[33m[0.098ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
[0m[33m[0.082ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
--- PASS: TestManager_Rollback_Failure (0.00s)
=== RUN   TestComputeEffectiveFlags_DefaultsNoDB
--- PASS: TestComputeEffectiveFlags_DefaultsNoDB (0.00s)
=== RUN   TestComputeEffectiveFlags_DB_CerberusDisabled

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.107ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" AND `settings`.`id` = 1 ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestComputeEffectiveFlags_DB_CerberusDisabled (0.00s)
=== RUN   TestComputeEffectiveFlags_DB_CrowdSecExternal

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.121ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestComputeEffectiveFlags_DB_CrowdSecExternal (0.00s)
=== RUN   TestComputeEffectiveFlags_DB_CrowdSecUnknown

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.110ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestComputeEffectiveFlags_DB_CrowdSecUnknown (0.00s)
=== RUN   TestComputeEffectiveFlags_DB_CrowdSecLocal

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.143ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestComputeEffectiveFlags_DB_CrowdSecLocal (0.00s)
=== RUN   TestComputeEffectiveFlags_DB_ACLTrueAndFalse

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.103ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.083ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestComputeEffectiveFlags_DB_ACLTrueAndFalse (0.00s)
=== RUN   TestComputeEffectiveFlags_DB_WAFMonitor

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestComputeEffectiveFlags_DB_WAFMonitor (0.00s)
=== RUN   TestManager_ApplyConfig_WAFMonitor

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestManager_ApplyConfig_WAFMonitor (0.01s)
=== RUN   TestNormalizeAdvancedConfig_MapWithNestedHandles
--- PASS: TestNormalizeAdvancedConfig_MapWithNestedHandles (0.00s)
=== RUN   TestNormalizeAdvancedConfig_ArrayTopLevel
--- PASS: TestNormalizeAdvancedConfig_ArrayTopLevel (0.00s)
=== RUN   TestNormalizeAdvancedConfig_DefaultPrimitives
--- PASS: TestNormalizeAdvancedConfig_DefaultPrimitives (0.00s)
=== RUN   TestNormalizeAdvancedConfig_CoerceNonStandardTypes
--- PASS: TestNormalizeAdvancedConfig_CoerceNonStandardTypes (0.00s)
=== RUN   TestNormalizeAdvancedConfig_JSONRoundtrip
--- PASS: TestNormalizeAdvancedConfig_JSONRoundtrip (0.00s)
=== RUN   TestNormalizeAdvancedConfig_TopLevelHeaders
--- PASS: TestNormalizeAdvancedConfig_TopLevelHeaders (0.00s)
=== RUN   TestNormalizeAdvancedConfig_HeadersAlreadyArray
--- PASS: TestNormalizeAdvancedConfig_HeadersAlreadyArray (0.00s)
=== RUN   TestNormalizeAdvancedConfig_MapWithTopLevelHandle
--- PASS: TestNormalizeAdvancedConfig_MapWithTopLevelHandle (0.00s)
=== RUN   TestReverseProxyHandler_PlexAndOthers
--- PASS: TestReverseProxyHandler_PlexAndOthers (0.00s)
=== RUN   TestHandlers
--- PASS: TestHandlers (0.00s)
=== RUN   TestValidate_NilConfig
--- PASS: TestValidate_NilConfig (0.00s)
=== RUN   TestValidateHandler_MissingHandlerField
--- PASS: TestValidateHandler_MissingHandlerField (0.00s)
=== RUN   TestValidateHandler_UnknownHandlerAllowed
--- PASS: TestValidateHandler_UnknownHandlerAllowed (0.00s)
=== RUN   TestValidateHandler_FileServerAndStaticResponseAllowed
--- PASS: TestValidateHandler_FileServerAndStaticResponseAllowed (0.00s)
=== RUN   TestValidateRoute_InvalidHandler
--- PASS: TestValidateRoute_InvalidHandler (0.00s)
=== RUN   TestValidateListenAddr_InvalidHostName
--- PASS: TestValidateListenAddr_InvalidHostName (0.00s)
=== RUN   TestValidateListenAddr_InvalidPortNonNumeric
--- PASS: TestValidateListenAddr_InvalidPortNonNumeric (0.00s)
=== RUN   TestValidate_MarshalError
--- PASS: TestValidate_MarshalError (0.00s)
=== RUN   TestValidate_EmptyConfig
--- PASS: TestValidate_EmptyConfig (0.00s)
=== RUN   TestValidate_ValidConfig
--- PASS: TestValidate_ValidConfig (0.00s)
=== RUN   TestValidate_DuplicateHosts
--- PASS: TestValidate_DuplicateHosts (0.00s)
=== RUN   TestValidate_NoListenAddresses
--- PASS: TestValidate_NoListenAddresses (0.00s)
=== RUN   TestValidate_InvalidPort
--- PASS: TestValidate_InvalidPort (0.00s)
=== RUN   TestValidate_NoHandlers
--- PASS: TestValidate_NoHandlers (0.00s)
=== RUN   TestValidateListenAddr
=== RUN   TestValidateListenAddr/Valid
=== RUN   TestValidateListenAddr/ValidIP
=== RUN   TestValidateListenAddr/ValidTCP
=== RUN   TestValidateListenAddr/ValidUDP
=== RUN   TestValidateListenAddr/InvalidFormat
=== RUN   TestValidateListenAddr/InvalidPort
=== RUN   TestValidateListenAddr/InvalidPortNegative
=== RUN   TestValidateListenAddr/InvalidIP
--- PASS: TestValidateListenAddr (0.00s)
    --- PASS: TestValidateListenAddr/Valid (0.00s)
    --- PASS: TestValidateListenAddr/ValidIP (0.00s)
    --- PASS: TestValidateListenAddr/ValidTCP (0.00s)
    --- PASS: TestValidateListenAddr/ValidUDP (0.00s)
    --- PASS: TestValidateListenAddr/InvalidFormat (0.00s)
    --- PASS: TestValidateListenAddr/InvalidPort (0.00s)
    --- PASS: TestValidateListenAddr/InvalidPortNegative (0.00s)
    --- PASS: TestValidateListenAddr/InvalidIP (0.00s)
=== RUN   TestValidateReverseProxy
=== RUN   TestValidateReverseProxy/Valid
=== RUN   TestValidateReverseProxy/MissingUpstreams
=== RUN   TestValidateReverseProxy/EmptyUpstreams
=== RUN   TestValidateReverseProxy/MissingDial
=== RUN   TestValidateReverseProxy/InvalidDial
--- PASS: TestValidateReverseProxy (0.00s)
    --- PASS: TestValidateReverseProxy/Valid (0.00s)
    --- PASS: TestValidateReverseProxy/MissingUpstreams (0.00s)
    --- PASS: TestValidateReverseProxy/EmptyUpstreams (0.00s)
    --- PASS: TestValidateReverseProxy/MissingDial (0.00s)
    --- PASS: TestValidateReverseProxy/InvalidDial (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/caddy	(cached)
=== RUN   TestIsEnabled_ConfigTrue
--- PASS: TestIsEnabled_ConfigTrue (0.00s)
=== RUN   TestIsEnabled_WAFModeEnabled
--- PASS: TestIsEnabled_WAFModeEnabled (0.00s)
=== RUN   TestIsEnabled_ACLModeEnabled
--- PASS: TestIsEnabled_ACLModeEnabled (0.00s)
=== RUN   TestIsEnabled_RateLimitModeEnabled
--- PASS: TestIsEnabled_RateLimitModeEnabled (0.00s)
=== RUN   TestIsEnabled_CrowdSecModeLocal
--- PASS: TestIsEnabled_CrowdSecModeLocal (0.00s)
=== RUN   TestIsEnabled_DBSetting_FeatureFlag
--- PASS: TestIsEnabled_DBSetting_FeatureFlag (0.00s)
=== RUN   TestIsEnabled_DBSetting_LegacyKey

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/cerberus/cerberus.go:57 [35;1mrecord not found
[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestIsEnabled_DBSetting_LegacyKey (0.00s)
=== RUN   TestIsEnabled_DBSetting_FeatureFlagTakesPrecedence
--- PASS: TestIsEnabled_DBSetting_FeatureFlagTakesPrecedence (0.00s)
=== RUN   TestIsEnabled_DBSettingCaseInsensitive
--- PASS: TestIsEnabled_DBSettingCaseInsensitive (0.00s)
=== RUN   TestIsEnabled_DBSettingFalse
--- PASS: TestIsEnabled_DBSettingFalse (0.00s)
=== RUN   TestIsEnabled_DefaultTrue
--- PASS: TestIsEnabled_DefaultTrue (0.00s)
=== RUN   TestMiddleware_WAFEnabledTracksMetrics
--- PASS: TestMiddleware_WAFEnabledTracksMetrics (0.00s)
=== RUN   TestMiddleware_ACLBlocksClientIP

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1mno such table: notification_configs
[0m[33m[0.147ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestMiddleware_ACLBlocksClientIP (0.00s)
=== RUN   TestMiddleware_ACLAllowsClientIP
--- PASS: TestMiddleware_ACLAllowsClientIP (0.00s)
=== RUN   TestMiddleware_NotEnabledSkips

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/cerberus/cerberus.go:57 [35;1mrecord not found
[0m[33m[0.050ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/cerberus/cerberus.go:61 [35;1mrecord not found
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestMiddleware_NotEnabledSkips (0.00s)
=== RUN   TestMiddleware_WAFPassesWithNoPayload
--- PASS: TestMiddleware_WAFPassesWithNoPayload (0.00s)
=== RUN   TestMiddleware_WAFMonitorLogsButDoesNotBlock
--- PASS: TestMiddleware_WAFMonitorLogsButDoesNotBlock (0.00s)
=== RUN   TestMiddleware_ACLDisabledDoesNotBlock
--- PASS: TestMiddleware_ACLDisabledDoesNotBlock (0.00s)
=== RUN   TestCerberus_IsEnabled_ConfigTrue
--- PASS: TestCerberus_IsEnabled_ConfigTrue (0.00s)
=== RUN   TestCerberus_IsEnabled_DBSetting
--- PASS: TestCerberus_IsEnabled_DBSetting (0.00s)
=== RUN   TestCerberus_IsEnabled_Disabled
    cerberus_test.go:68: cfg: {CrowdSecMode: CrowdSecAPIURL: CrowdSecAPIKey: CrowdSecConfigDir: WAFMode: RateLimitMode: ACLMode: CerberusEnabled:false}
    cerberus_test.go:69: IsEnabled() -> false
--- PASS: TestCerberus_IsEnabled_Disabled (0.00s)
=== RUN   TestCerberus_IsEnabled_CrowdSecLocal
--- PASS: TestCerberus_IsEnabled_CrowdSecLocal (0.00s)
=== RUN   TestCerberus_IsEnabled_WAFEnabled
--- PASS: TestCerberus_IsEnabled_WAFEnabled (0.00s)
=== RUN   TestCerberus_IsEnabled_RateLimitEnabled
--- PASS: TestCerberus_IsEnabled_RateLimitEnabled (0.00s)
=== RUN   TestCerberus_IsEnabled_ACLEnabled
--- PASS: TestCerberus_IsEnabled_ACLEnabled (0.00s)
=== RUN   TestCerberus_IsEnabled_LegacySetting

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/cerberus/cerberus.go:57 [35;1mrecord not found
[0m[33m[0.055ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
--- PASS: TestCerberus_IsEnabled_LegacySetting (0.00s)
=== RUN   TestCerberus_Middleware_Disabled
--- PASS: TestCerberus_Middleware_Disabled (0.00s)
=== RUN   TestCerberus_Middleware_WAFEnabled
--- PASS: TestCerberus_Middleware_WAFEnabled (0.00s)
=== RUN   TestCerberus_Middleware_ACLEnabled_NoAccessLists
--- PASS: TestCerberus_Middleware_ACLEnabled_NoAccessLists (0.00s)
=== RUN   TestCerberus_Middleware_ACLEnabled_DisabledList
--- PASS: TestCerberus_Middleware_ACLEnabled_DisabledList (0.00s)
=== RUN   TestCerberus_Middleware_ACLEnabled_Blocked

2025/12/12 19:01:40 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1mno such table: notification_configs
[0m[33m[0.091ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestCerberus_Middleware_ACLEnabled_Blocked (0.00s)
=== RUN   TestCerberus_Middleware_CrowdSecLocal
--- PASS: TestCerberus_Middleware_CrowdSecLocal (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/cerberus	(cached)
=== RUN   TestLoad
--- PASS: TestLoad (0.00s)
=== RUN   TestLoad_Defaults
--- PASS: TestLoad_Defaults (0.00s)
=== RUN   TestLoad_CharonPrefersOverCPM
--- PASS: TestLoad_CharonPrefersOverCPM (0.00s)
=== RUN   TestLoad_Error
--- PASS: TestLoad_Error (0.00s)
=== RUN   TestGetEnvAny
--- PASS: TestGetEnvAny (0.00s)
=== RUN   TestLoad_SecurityConfig
--- PASS: TestLoad_SecurityConfig (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/config	(cached)
=== RUN   TestConsoleEnrollSuccess
time="2025-12-12T19:01:41Z" level=info msg="registering with crowdsec capi"

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
time="2025-12-12T19:01:41Z" level=info msg="starting crowdsec console enrollment" agent=agent-one correlation_id=df46e443-0155-4b28-945a-230170728d23 tenant=tenant-a
time="2025-12-12T19:01:41Z" level=info msg="crowdsec console enrollment succeeded" agent=agent-one correlation_id=df46e443-0155-4b28-945a-230170728d23 tenant=tenant-a
--- PASS: TestConsoleEnrollSuccess (0.00s)
=== RUN   TestConsoleEnrollFailureRedactsSecret
time="2025-12-12T19:01:41Z" level=info msg="registering with crowdsec capi"

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
time="2025-12-12T19:01:41Z" level=info msg="starting crowdsec console enrollment" agent=agent correlation_id=6bf8692d-798b-44ae-b4e9-7a5d65b616e3 tenant=tenant
time="2025-12-12T19:01:41Z" level=warning msg="crowdsec console enrollment failed" correlation_id=6bf8692d-798b-44ae-b4e9-7a5d65b616e3 error="bad key secretKEY123" tenant=tenant
--- PASS: TestConsoleEnrollFailureRedactsSecret (0.00s)
=== RUN   TestConsoleEnrollIdempotentWhenAlreadyEnrolled
time="2025-12-12T19:01:41Z" level=info msg="registering with crowdsec capi"

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.067ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
time="2025-12-12T19:01:41Z" level=info msg="starting crowdsec console enrollment" agent=agent correlation_id=692144ad-efa0-4997-a2a9-8cd9134ad766 tenant=tenant
time="2025-12-12T19:01:41Z" level=info msg="crowdsec console enrollment succeeded" agent=agent correlation_id=692144ad-efa0-4997-a2a9-8cd9134ad766 tenant=tenant
time="2025-12-12T19:01:41Z" level=info msg="registering with crowdsec capi"
--- PASS: TestConsoleEnrollIdempotentWhenAlreadyEnrolled (0.00s)
=== RUN   TestConsoleEnrollBlockedWhenInProgress
time="2025-12-12T19:01:41Z" level=info msg="registering with crowdsec capi"
--- PASS: TestConsoleEnrollBlockedWhenInProgress (0.00s)
=== RUN   TestConsoleEnrollNormalizesFullCommand
time="2025-12-12T19:01:41Z" level=info msg="registering with crowdsec capi"

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
time="2025-12-12T19:01:41Z" level=info msg="starting crowdsec console enrollment" agent=agent correlation_id=8296e2c1-9961-49ee-82d2-8bc879ee6daa tenant=tenant
time="2025-12-12T19:01:41Z" level=info msg="crowdsec console enrollment succeeded" agent=agent correlation_id=8296e2c1-9961-49ee-82d2-8bc879ee6daa tenant=tenant
--- PASS: TestConsoleEnrollNormalizesFullCommand (0.00s)
=== RUN   TestConsoleEnrollRejectsUnsafeInput
--- PASS: TestConsoleEnrollRejectsUnsafeInput (0.00s)
=== RUN   TestConsoleEnrollDoesNotPassTenant
time="2025-12-12T19:01:41Z" level=info msg="registering with crowdsec capi"

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
time="2025-12-12T19:01:41Z" level=info msg="starting crowdsec console enrollment" agent=agent-one correlation_id=9f74947b-fe45-466d-beea-16cec52a8b3d tenant=some-tenant-id
time="2025-12-12T19:01:41Z" level=info msg="crowdsec console enrollment succeeded" agent=agent-one correlation_id=9f74947b-fe45-466d-beea-16cec52a8b3d tenant=some-tenant-id
--- PASS: TestConsoleEnrollDoesNotPassTenant (0.00s)
=== RUN   TestSecureCommandExecutorExecuteWithEnv
=== RUN   TestSecureCommandExecutorExecuteWithEnv/executes_command_successfully
=== RUN   TestSecureCommandExecutorExecuteWithEnv/passes_environment_variables
=== RUN   TestSecureCommandExecutorExecuteWithEnv/handles_empty_env_map
=== RUN   TestSecureCommandExecutorExecuteWithEnv/handles_command_failure
=== RUN   TestSecureCommandExecutorExecuteWithEnv/handles_context_timeout
--- PASS: TestSecureCommandExecutorExecuteWithEnv (0.01s)
    --- PASS: TestSecureCommandExecutorExecuteWithEnv/executes_command_successfully (0.00s)
    --- PASS: TestSecureCommandExecutorExecuteWithEnv/passes_environment_variables (0.00s)
    --- PASS: TestSecureCommandExecutorExecuteWithEnv/handles_empty_env_map (0.00s)
    --- PASS: TestSecureCommandExecutorExecuteWithEnv/handles_command_failure (0.00s)
    --- PASS: TestSecureCommandExecutorExecuteWithEnv/handles_context_timeout (0.00s)
=== RUN   TestFormatEnv
=== RUN   TestFormatEnv/formats_single_env_var
=== RUN   TestFormatEnv/formats_multiple_env_vars
=== RUN   TestFormatEnv/handles_empty_map
=== RUN   TestFormatEnv/handles_nil_map
=== RUN   TestFormatEnv/handles_special_characters
--- PASS: TestFormatEnv (0.00s)
    --- PASS: TestFormatEnv/formats_single_env_var (0.00s)
    --- PASS: TestFormatEnv/formats_multiple_env_vars (0.00s)
    --- PASS: TestFormatEnv/handles_empty_map (0.00s)
    --- PASS: TestFormatEnv/handles_nil_map (0.00s)
    --- PASS: TestFormatEnv/handles_special_characters (0.00s)
=== RUN   TestConsoleEnrollmentStatus
=== RUN   TestConsoleEnrollmentStatus/returns_not_enrolled_for_new_service

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
=== RUN   TestConsoleEnrollmentStatus/returns_enrolled_status_after_enrollment
time="2025-12-12T19:01:41Z" level=info msg="registering with crowdsec capi"

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.062ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
time="2025-12-12T19:01:41Z" level=info msg="starting crowdsec console enrollment" agent=test-agent correlation_id=f9d8cff5-2328-4d76-99ae-8ad77cabe7c5 tenant=
time="2025-12-12T19:01:41Z" level=info msg="crowdsec console enrollment succeeded" agent=test-agent correlation_id=f9d8cff5-2328-4d76-99ae-8ad77cabe7c5 tenant=
=== RUN   TestConsoleEnrollmentStatus/returns_failed_status_after_failed_enrollment
time="2025-12-12T19:01:41Z" level=info msg="registering with crowdsec capi"

2025/12/12 19:01:41 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
[0m[33m[0.058ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
time="2025-12-12T19:01:41Z" level=info msg="starting crowdsec console enrollment" agent=test-agent correlation_id=2d72088a-f808-4327-a1b3-331ca36debc4 tenant=
time="2025-12-12T19:01:41Z" level=warning msg="crowdsec console enrollment failed" correlation_id=2d72088a-f808-4327-a1b3-331ca36debc4 error="enroll failed" tenant=
--- PASS: TestConsoleEnrollmentStatus (0.01s)
    --- PASS: TestConsoleEnrollmentStatus/returns_not_enrolled_for_new_service (0.00s)
    --- PASS: TestConsoleEnrollmentStatus/returns_enrolled_status_after_enrollment (0.00s)
    --- PASS: TestConsoleEnrollmentStatus/returns_failed_status_after_failed_enrollment (0.00s)
=== RUN   TestDeriveKey
=== RUN   TestDeriveKey/derives_consistent_key
=== RUN   TestDeriveKey/derives_different_keys_for_different_secrets
=== RUN   TestDeriveKey/uses_default_for_empty_secret
--- PASS: TestDeriveKey (0.00s)
    --- PASS: TestDeriveKey/derives_consistent_key (0.00s)
    --- PASS: TestDeriveKey/derives_different_keys_for_different_secrets (0.00s)
    --- PASS: TestDeriveKey/uses_default_for_empty_secret (0.00s)
=== RUN   TestNormalizeEnrollmentKey
=== RUN   TestNormalizeEnrollmentKey/valid_raw_key
=== RUN   TestNormalizeEnrollmentKey/full_command_with_sudo
=== RUN   TestNormalizeEnrollmentKey/full_command_without_sudo
=== RUN   TestNormalizeEnrollmentKey/key_with_whitespace
=== RUN   TestNormalizeEnrollmentKey/empty_key
=== RUN   TestNormalizeEnrollmentKey/only_whitespace
=== RUN   TestNormalizeEnrollmentKey/invalid_format
=== RUN   TestNormalizeEnrollmentKey/injection_attempt
--- PASS: TestNormalizeEnrollmentKey (0.00s)
    --- PASS: TestNormalizeEnrollmentKey/valid_raw_key (0.00s)
    --- PASS: TestNormalizeEnrollmentKey/full_command_with_sudo (0.00s)
    --- PASS: TestNormalizeEnrollmentKey/full_command_without_sudo (0.00s)
    --- PASS: TestNormalizeEnrollmentKey/key_with_whitespace (0.00s)
    --- PASS: TestNormalizeEnrollmentKey/empty_key (0.00s)
    --- PASS: TestNormalizeEnrollmentKey/only_whitespace (0.00s)
    --- PASS: TestNormalizeEnrollmentKey/invalid_format (0.00s)
    --- PASS: TestNormalizeEnrollmentKey/injection_attempt (0.00s)
=== RUN   TestRedactSecret
=== RUN   TestRedactSecret/redacts_secret_from_message
=== RUN   TestRedactSecret/handles_empty_secret
=== RUN   TestRedactSecret/handles_secret_not_in_message
=== RUN   TestRedactSecret/redacts_multiple_occurrences
--- PASS: TestRedactSecret (0.00s)
    --- PASS: TestRedactSecret/redacts_secret_from_message (0.00s)
    --- PASS: TestRedactSecret/handles_empty_secret (0.00s)
    --- PASS: TestRedactSecret/handles_secret_not_in_message (0.00s)
    --- PASS: TestRedactSecret/redacts_multiple_occurrences (0.00s)
=== RUN   TestEncryptDecrypt
=== RUN   TestEncryptDecrypt/encrypts_and_decrypts_successfully
=== RUN   TestEncryptDecrypt/handles_empty_string
=== RUN   TestEncryptDecrypt/different_encryptions_produce_different_ciphertext
--- PASS: TestEncryptDecrypt (0.00s)
    --- PASS: TestEncryptDecrypt/encrypts_and_decrypts_successfully (0.00s)
    --- PASS: TestEncryptDecrypt/handles_empty_string (0.00s)
    --- PASS: TestEncryptDecrypt/different_encryptions_produce_different_ciphertext (0.00s)
=== RUN   TestApplyWithOpenFileHandles
time="2025-12-12T19:01:41Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyWithOpenFileHandles1577121141/001/test/preset/bundle.tgz cache_key=test/preset-1765566101 meta_path=/tmp/TestApplyWithOpenFileHandles1577121141/001/test/preset/metadata.json preview_path=/tmp/TestApplyWithOpenFileHandles1577121141/001/test/preset/preview.yaml slug=test/preset
time="2025-12-12T19:01:41Z" level=info msg="successfully loaded cached preset metadata" archive_path=/tmp/TestApplyWithOpenFileHandles1577121141/001/test/preset/bundle.tgz cache_key=test/preset-1765566101 slug=test/preset
--- PASS: TestApplyWithOpenFileHandles (0.00s)
=== RUN   TestBackupPathOnlySetAfterSuccessfulBackup
=== RUN   TestBackupPathOnlySetAfterSuccessfulBackup/backup_path_not_set_when_cache_missing
time="2025-12-12T19:01:41Z" level=warning msg="failed to load cached preset metadata" error="cache miss" slug=nonexistent/preset
time="2025-12-12T19:01:41Z" level=info msg="attempting to repull preset after cache load failure" error="load cache for nonexistent/preset: cache miss" slug=nonexistent/preset
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=1 error="https://hub-data.crowdsec.net/api/index.json (status 403)" hub_index="https://hub-data.crowdsec.net/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=true hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json"
time="2025-12-12T19:01:42Z" level=warning msg="cache refresh failed; rolled back backup" backup_path=/tmp/TestBackupPathOnlySetAfterSuccessfulBackupbackup_path_not_set_w3329883887/002/crowdsec.backup.20251212-190141 error="load cache for nonexistent/preset: cache miss: refresh cache: preset not found in hub" slug=nonexistent/preset
=== RUN   TestBackupPathOnlySetAfterSuccessfulBackup/backup_path_set_only_after_successful_backup
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestBackupPathOnlySetAfterSuccessfulBackupbackup_path_set_only_3319044631/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 meta_path=/tmp/TestBackupPathOnlySetAfterSuccessfulBackupbackup_path_set_only_3319044631/001/test/preset/metadata.json preview_path=/tmp/TestBackupPathOnlySetAfterSuccessfulBackupbackup_path_set_only_3319044631/001/test/preset/preview.yaml slug=test/preset
time="2025-12-12T19:01:42Z" level=info msg="successfully loaded cached preset metadata" archive_path=/tmp/TestBackupPathOnlySetAfterSuccessfulBackupbackup_path_set_only_3319044631/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 slug=test/preset
--- PASS: TestBackupPathOnlySetAfterSuccessfulBackup (0.60s)
    --- PASS: TestBackupPathOnlySetAfterSuccessfulBackup/backup_path_not_set_when_cache_missing (0.59s)
    --- PASS: TestBackupPathOnlySetAfterSuccessfulBackup/backup_path_set_only_after_successful_backup (0.00s)
=== RUN   TestHubCacheStoreLoadAndExpire
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestHubCacheStoreLoadAndExpire451730120/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestHubCacheStoreLoadAndExpire451730120/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestHubCacheStoreLoadAndExpire451730120/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestHubCacheStoreLoadAndExpire (0.00s)
=== RUN   TestHubCacheRejectsBadSlug
--- PASS: TestHubCacheRejectsBadSlug (0.00s)
=== RUN   TestHubCacheListAndEvict
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestHubCacheListAndEvict2059688537/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestHubCacheListAndEvict2059688537/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestHubCacheListAndEvict2059688537/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestHubCacheListAndEvict2059688537/001/crowdsecurity/other/bundle.tgz cache_key=crowdsecurity/other-1765566102 meta_path=/tmp/TestHubCacheListAndEvict2059688537/001/crowdsecurity/other/metadata.json preview_path=/tmp/TestHubCacheListAndEvict2059688537/001/crowdsecurity/other/preview.yaml slug=crowdsecurity/other
--- PASS: TestHubCacheListAndEvict (0.00s)
=== RUN   TestHubCacheTouchUpdatesTTL
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestHubCacheTouchUpdatesTTL763022005/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestHubCacheTouchUpdatesTTL763022005/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestHubCacheTouchUpdatesTTL763022005/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestHubCacheTouchUpdatesTTL (0.00s)
=== RUN   TestHubCachePreviewExistsAndSize
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestHubCachePreviewExistsAndSize3876473300/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestHubCachePreviewExistsAndSize3876473300/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestHubCachePreviewExistsAndSize3876473300/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestHubCachePreviewExistsAndSize (0.00s)
=== RUN   TestHubCacheExistsHonorsTTL
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestHubCacheExistsHonorsTTL419723857/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestHubCacheExistsHonorsTTL419723857/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestHubCacheExistsHonorsTTL419723857/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestHubCacheExistsHonorsTTL (0.00s)
=== RUN   TestSanitizeSlugCases
--- PASS: TestSanitizeSlugCases (0.00s)
=== RUN   TestNewHubCacheRequiresBaseDir
--- PASS: TestNewHubCacheRequiresBaseDir (0.00s)
=== RUN   TestHubCacheTouchMissing
--- PASS: TestHubCacheTouchMissing (0.00s)
=== RUN   TestHubCacheTouchInvalidSlug
--- PASS: TestHubCacheTouchInvalidSlug (0.00s)
=== RUN   TestHubCacheStoreContextCanceled
--- PASS: TestHubCacheStoreContextCanceled (0.00s)
=== RUN   TestHubCacheLoadInvalidSlug
--- PASS: TestHubCacheLoadInvalidSlug (0.00s)
=== RUN   TestHubCacheExistsContextCanceled
--- PASS: TestHubCacheExistsContextCanceled (0.00s)
=== RUN   TestHubCacheListSkipsExpired
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestHubCacheListSkipsExpired2609582306/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1704110400 meta_path=/tmp/TestHubCacheListSkipsExpired2609582306/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestHubCacheListSkipsExpired2609582306/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestHubCacheListSkipsExpired (0.00s)
=== RUN   TestHubCacheEvictInvalidSlug
--- PASS: TestHubCacheEvictInvalidSlug (0.00s)
=== RUN   TestHubCacheListContextCanceled
--- PASS: TestHubCacheListContextCanceled (0.00s)
=== RUN   TestHubCacheTTL
=== RUN   TestHubCacheTTL/returns_configured_TTL
=== RUN   TestHubCacheTTL/returns_minute_TTL
=== RUN   TestHubCacheTTL/returns_zero_TTL_if_configured
--- PASS: TestHubCacheTTL (0.00s)
    --- PASS: TestHubCacheTTL/returns_configured_TTL (0.00s)
    --- PASS: TestHubCacheTTL/returns_minute_TTL (0.00s)
    --- PASS: TestHubCacheTTL/returns_zero_TTL_if_configured (0.00s)
=== RUN   TestPullThenApplyFlow
    hub_pull_apply_test.go:90: Step 1: Pulling preset
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://test.example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/test.tgz" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/test.yaml" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=158 etag=etag123 hub_endpoint="http://test.example.com/test.tgz" preview_size=24 slug=test/preset
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestPullThenApplyFlow466905016/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 meta_path=/tmp/TestPullThenApplyFlow466905016/001/test/preset/metadata.json preview_path=/tmp/TestPullThenApplyFlow466905016/001/test/preset/preview.yaml slug=test/preset
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestPullThenApplyFlow466905016/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 preview_path=/tmp/TestPullThenApplyFlow466905016/001/test/preset/preview.yaml slug=test/preset
    hub_pull_apply_test.go:110: Step 2: Verifying cache can be loaded
    hub_pull_apply_test.go:117: Step 3: Applying preset from cache
time="2025-12-12T19:01:42Z" level=info msg="successfully loaded cached preset metadata" archive_path=/tmp/TestPullThenApplyFlow466905016/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 slug=test/preset
--- PASS: TestPullThenApplyFlow (0.00s)
=== RUN   TestApplyRepullsOnCacheMissAfterCSCLIFailure
time="2025-12-12T19:01:42Z" level=warning msg="failed to load cached preset metadata" error="cache miss" slug=test/preset
time="2025-12-12T19:01:42Z" level=warning msg="cscli install failed; attempting cache fallback" error="install failed" slug=test/preset
time="2025-12-12T19:01:42Z" level=info msg="attempting to repull preset after cache load failure" error="load cache for test/preset: cache miss" slug=test/preset
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://test.example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/test/preset.tgz" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/test/preset.yaml" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=110 etag=e1 hub_endpoint="http://test.example.com/test/preset.tgz" preview_size=7 slug=test/preset
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyRepullsOnCacheMissAfterCSCLIFailure2942444691/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 meta_path=/tmp/TestApplyRepullsOnCacheMissAfterCSCLIFailure2942444691/001/test/preset/metadata.json preview_path=/tmp/TestApplyRepullsOnCacheMissAfterCSCLIFailure2942444691/001/test/preset/preview.yaml slug=test/preset
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestApplyRepullsOnCacheMissAfterCSCLIFailure2942444691/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 preview_path=/tmp/TestApplyRepullsOnCacheMissAfterCSCLIFailure2942444691/001/test/preset/preview.yaml slug=test/preset
--- PASS: TestApplyRepullsOnCacheMissAfterCSCLIFailure (0.00s)
=== RUN   TestApplyRepullsOnCacheExpired
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyRepullsOnCacheExpired3802500890/001/expired/preset/bundle.tgz cache_key=expired/preset-1765566102 meta_path=/tmp/TestApplyRepullsOnCacheExpired3802500890/001/expired/preset/metadata.json preview_path=/tmp/TestApplyRepullsOnCacheExpired3802500890/001/expired/preset/preview.yaml slug=expired/preset
time="2025-12-12T19:01:42Z" level=warning msg="failed to load cached preset metadata" error="cache expired" slug=expired/preset
time="2025-12-12T19:01:42Z" level=info msg="attempting to repull preset after cache load failure" error="load cache for expired/preset: cache expired" slug=expired/preset
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://test.example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/expired/preset.tgz" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/expired/preset.yaml" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=112 etag=e2 hub_endpoint="http://test.example.com/expired/preset.tgz" preview_size=11 slug=expired/preset
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyRepullsOnCacheExpired3802500890/001/expired/preset/bundle.tgz cache_key=expired/preset-1765566102 meta_path=/tmp/TestApplyRepullsOnCacheExpired3802500890/001/expired/preset/metadata.json preview_path=/tmp/TestApplyRepullsOnCacheExpired3802500890/001/expired/preset/preview.yaml slug=expired/preset
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestApplyRepullsOnCacheExpired3802500890/001/expired/preset/bundle.tgz cache_key=expired/preset-1765566102 preview_path=/tmp/TestApplyRepullsOnCacheExpired3802500890/001/expired/preset/preview.yaml slug=expired/preset
--- PASS: TestApplyRepullsOnCacheExpired (0.01s)
=== RUN   TestPullAcceptsNamespacedIndexEntry
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://test.example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/crowdsecurity/bot-mitigation-essentials.tgz" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/crowdsecurity/bot-mitigation-essentials.yaml" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=114 etag=etag-bme hub_endpoint="http://test.example.com/crowdsecurity/bot-mitigation-essentials.tgz" preview_size=18 slug=bot-mitigation-essentials
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestPullAcceptsNamespacedIndexEntry475100233/001/bot-mitigation-essentials/bundle.tgz cache_key=bot-mitigation-essentials-1765566102 meta_path=/tmp/TestPullAcceptsNamespacedIndexEntry475100233/001/bot-mitigation-essentials/metadata.json preview_path=/tmp/TestPullAcceptsNamespacedIndexEntry475100233/001/bot-mitigation-essentials/preview.yaml slug=bot-mitigation-essentials
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestPullAcceptsNamespacedIndexEntry475100233/001/bot-mitigation-essentials/bundle.tgz cache_key=bot-mitigation-essentials-1765566102 preview_path=/tmp/TestPullAcceptsNamespacedIndexEntry475100233/001/bot-mitigation-essentials/preview.yaml slug=bot-mitigation-essentials
--- PASS: TestPullAcceptsNamespacedIndexEntry (0.00s)
=== RUN   TestHubFallbackToMirrorOnForbidden
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=1 error="http://primary.example.com/api/index.json (status 403)" hub_index="http://primary.example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=true hub_index="http://mirror.example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub fetch failed, attempting fallback" attempt=1 endpoint="http://primary.example.com/fallback/preset.tgz" error="http://primary.example.com/fallback/preset.tgz (status 403)"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://mirror.example.com/fallback/preset.tgz" fallback_used=true
time="2025-12-12T19:01:42Z" level=warning msg="hub fetch failed, attempting fallback" attempt=1 endpoint="http://primary.example.com/fallback/preset.yaml" error="http://primary.example.com/fallback/preset.yaml (status 403)"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://mirror.example.com/fallback/preset.yaml" fallback_used=true
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=104 etag=etag-mirror hub_endpoint="http://mirror.example.com/fallback/preset.tgz" preview_size=14 slug=fallback/preset
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestHubFallbackToMirrorOnForbidden2346863733/001/fallback/preset/bundle.tgz cache_key=fallback/preset-1765566102 meta_path=/tmp/TestHubFallbackToMirrorOnForbidden2346863733/001/fallback/preset/metadata.json preview_path=/tmp/TestHubFallbackToMirrorOnForbidden2346863733/001/fallback/preset/preview.yaml slug=fallback/preset
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestHubFallbackToMirrorOnForbidden2346863733/001/fallback/preset/bundle.tgz cache_key=fallback/preset-1765566102 preview_path=/tmp/TestHubFallbackToMirrorOnForbidden2346863733/001/fallback/preset/preview.yaml slug=fallback/preset
--- PASS: TestHubFallbackToMirrorOnForbidden (0.00s)
=== RUN   TestApplyWithoutPullFails
time="2025-12-12T19:01:42Z" level=warning msg="failed to load cached preset metadata" error="cache miss" slug=nonexistent/preset
time="2025-12-12T19:01:42Z" level=info msg="attempting to repull preset after cache load failure" error="load cache for nonexistent/preset: cache miss" slug=nonexistent/preset
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=1 error="http://test.example.com/api/index.json (status 500)" hub_index="http://test.example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=2 error="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json (status 500)" hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=3 error="https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json (status 500)" hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=4 error="https://hub-data.crowdsec.net/api/index.json (status 500)" hub_index="https://hub-data.crowdsec.net/api/index.json"
time="2025-12-12T19:01:42Z" level=warning msg="cache refresh failed; rolled back backup" backup_path=/tmp/TestApplyWithoutPullFails3366600238/002.backup.20251212-190142 error="load cache for nonexistent/preset: cache miss: refresh cache: fetch hub index: http://test.example.com/api/index.json: http://test.example.com/api/index.json (status 500)\nhttps://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json (status 500)\nhttps://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json (status 500)\nhttps://hub-data.crowdsec.net/api/index.json: https://hub-data.crowdsec.net/api/index.json (status 500)" slug=nonexistent/preset
--- PASS: TestApplyWithoutPullFails (0.00s)
=== RUN   TestCacheExpiration
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestCacheExpiration1620386465/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 meta_path=/tmp/TestCacheExpiration1620386465/001/test/preset/metadata.json preview_path=/tmp/TestCacheExpiration1620386465/001/test/preset/preview.yaml slug=test/preset
--- PASS: TestCacheExpiration (0.01s)
=== RUN   TestCacheListAfterPull
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://test.example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/preset1.tgz" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://test.example.com/preset1.yaml" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=105 etag=e1 hub_endpoint="http://test.example.com/preset1.tgz" preview_size=8 slug=preset1
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestCacheListAfterPull1961094869/001/preset1/bundle.tgz cache_key=preset1-1765566102 meta_path=/tmp/TestCacheListAfterPull1961094869/001/preset1/metadata.json preview_path=/tmp/TestCacheListAfterPull1961094869/001/preset1/preview.yaml slug=preset1
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestCacheListAfterPull1961094869/001/preset1/bundle.tgz cache_key=preset1-1765566102 preview_path=/tmp/TestCacheListAfterPull1961094869/001/preset1/preview.yaml slug=preset1
--- PASS: TestCacheListAfterPull (0.00s)
=== RUN   TestApplyReadsArchiveBeforeBackup
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyReadsArchiveBeforeBackup1671951937/001/crowdsec/hub_cache/test/preset/bundle.tgz cache_key=test/preset-1765566102 meta_path=/tmp/TestApplyReadsArchiveBeforeBackup1671951937/001/crowdsec/hub_cache/test/preset/metadata.json preview_path=/tmp/TestApplyReadsArchiveBeforeBackup1671951937/001/crowdsec/hub_cache/test/preset/preview.yaml slug=test/preset
time="2025-12-12T19:01:42Z" level=info msg="successfully loaded cached preset metadata" archive_path=/tmp/TestApplyReadsArchiveBeforeBackup1671951937/001/crowdsec/hub_cache/test/preset/bundle.tgz cache_key=test/preset-1765566102 slug=test/preset
--- PASS: TestApplyReadsArchiveBeforeBackup (0.00s)
=== RUN   TestFetchIndexParsesRawIndexFormat
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://example.com/api/index.json"
--- PASS: TestFetchIndexParsesRawIndexFormat (0.00s)
=== RUN   TestFetchIndexPrefersCSCLI
--- PASS: TestFetchIndexPrefersCSCLI (0.00s)
=== RUN   TestFetchIndexFallbackHTTP
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://example.com/api/index.json"
--- PASS: TestFetchIndexFallbackHTTP (0.00s)
=== RUN   TestFetchIndexHTTPRejectsRedirect
--- PASS: TestFetchIndexHTTPRejectsRedirect (0.00s)
=== RUN   TestFetchIndexHTTPRejectsHTML
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=1 error="https://hub-data.crowdsec.net/api/index.json (status 200): hub index responded with HTML; install cscli or set HUB_BASE_URL to a JSON hub endpoint" hub_index="https://hub-data.crowdsec.net/api/index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=2 error="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json (status 200): hub index responded with HTML; install cscli or set HUB_BASE_URL to a JSON hub endpoint" hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=3 error="https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json (status 200): hub index responded with HTML; install cscli or set HUB_BASE_URL to a JSON hub endpoint" hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json"
--- PASS: TestFetchIndexHTTPRejectsHTML (0.00s)
=== RUN   TestFetchIndexHTTPFallsBackToDefaultHub
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="https://hub.crowdsec.net/api/index.json"
--- PASS: TestFetchIndexHTTPFallsBackToDefaultHub (0.00s)
=== RUN   TestFetchIndexFallsBackToMirrorOnForbidden
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=1 error="https://hub-data.crowdsec.net/api/index.json (status 403)" hub_index="https://hub-data.crowdsec.net/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=true hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json"
--- PASS: TestFetchIndexFallsBackToMirrorOnForbidden (0.00s)
=== RUN   TestPullCachesPreview
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://example.com/demo.tgz" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://example.com/demo.yaml" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=106 etag=etag1 hub_endpoint="http://example.com/demo.tgz" preview_size=12 slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestPullCachesPreview163764455/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestPullCachesPreview163764455/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestPullCachesPreview163764455/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestPullCachesPreview163764455/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 preview_path=/tmp/TestPullCachesPreview163764455/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestPullCachesPreview (0.00s)
=== RUN   TestApplyUsesCacheWhenCSCLIFails
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyUsesCacheWhenCSCLIFails3907435296/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestApplyUsesCacheWhenCSCLIFails3907435296/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestApplyUsesCacheWhenCSCLIFails3907435296/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="successfully loaded cached preset metadata" archive_path=/tmp/TestApplyUsesCacheWhenCSCLIFails3907435296/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=warning msg="cscli install failed; attempting cache fallback" error="install failed" slug=crowdsecurity/demo
--- PASS: TestApplyUsesCacheWhenCSCLIFails (0.00s)
=== RUN   TestApplyRollsBackOnBadArchive
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyRollsBackOnBadArchive1203944782/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestApplyRollsBackOnBadArchive1203944782/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestApplyRollsBackOnBadArchive1203944782/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="successfully loaded cached preset metadata" archive_path=/tmp/TestApplyRollsBackOnBadArchive1203944782/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 slug=crowdsecurity/demo
--- PASS: TestApplyRollsBackOnBadArchive (0.00s)
=== RUN   TestApplyUsesCacheWhenCscliMissing
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyUsesCacheWhenCscliMissing4071549477/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestApplyUsesCacheWhenCscliMissing4071549477/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestApplyUsesCacheWhenCscliMissing4071549477/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="successfully loaded cached preset metadata" archive_path=/tmp/TestApplyUsesCacheWhenCscliMissing4071549477/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 slug=crowdsecurity/demo
--- PASS: TestApplyUsesCacheWhenCscliMissing (0.00s)
=== RUN   TestPullReturnsCachedPreviewWithoutNetwork
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestPullReturnsCachedPreviewWithoutNetwork150266149/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestPullReturnsCachedPreviewWithoutNetwork150266149/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestPullReturnsCachedPreviewWithoutNetwork150266149/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestPullReturnsCachedPreviewWithoutNetwork (0.00s)
=== RUN   TestPullEvictsExpiredCacheAndRefreshes
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestPullEvictsExpiredCacheAndRefreshes2183426244/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566100 meta_path=/tmp/TestPullEvictsExpiredCacheAndRefreshes2183426244/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestPullEvictsExpiredCacheAndRefreshes2183426244/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://example.com/demo.tgz" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://example.com/demo.yaml" fallback_used=false
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=99 etag=etag2 hub_endpoint="http://example.com/demo.tgz" preview_size=13 slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestPullEvictsExpiredCacheAndRefreshes2183426244/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566103 meta_path=/tmp/TestPullEvictsExpiredCacheAndRefreshes2183426244/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestPullEvictsExpiredCacheAndRefreshes2183426244/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestPullEvictsExpiredCacheAndRefreshes2183426244/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566103 preview_path=/tmp/TestPullEvictsExpiredCacheAndRefreshes2183426244/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestPullEvictsExpiredCacheAndRefreshes (0.00s)
=== RUN   TestPullFallsBackToArchivePreview
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://example.com/api/index.json"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="http://example.com/demo.tgz" fallback_used=false
time="2025-12-12T19:01:42Z" level=warning msg="hub fetch failed, attempting fallback" attempt=1 endpoint="http://example.com/demo.yaml" error="http://example.com/demo.yaml (status 500)"
time="2025-12-12T19:01:42Z" level=warning msg="failed to download preview, falling back to archive inspection" error="preview fetch failed (last endpoint http://example.com/crowdsecurity/demo.yaml): http://example.com/demo.yaml: http://example.com/demo.yaml (status 500)\nhttp://example.com/crowdsecurity/demo.yaml: http://example.com/crowdsecurity/demo.yaml (status 404)" slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=116 etag=etag1 hub_endpoint="http://example.com/demo.tgz" preview_size=11 slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestPullFallsBackToArchivePreview1622869425/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestPullFallsBackToArchivePreview1622869425/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestPullFallsBackToArchivePreview1622869425/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestPullFallsBackToArchivePreview1622869425/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 preview_path=/tmp/TestPullFallsBackToArchivePreview1622869425/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestPullFallsBackToArchivePreview (0.00s)
=== RUN   TestPullFallsBackToMirrorArchiveOnForbidden
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="https://primary.example/api/index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub fetch failed, attempting fallback" attempt=1 endpoint="https://primary.example/crowdsecurity/demo.tgz" error="https://primary.example/crowdsecurity/demo.tgz (status 403)"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="https://raw.githubusercontent.com/crowdsecurity/hub/master/crowdsecurity/demo.tgz" fallback_used=true
time="2025-12-12T19:01:42Z" level=warning msg="hub fetch failed, attempting fallback" attempt=1 endpoint="https://primary.example/crowdsecurity/demo.yaml" error="https://primary.example/crowdsecurity/demo.yaml (status 403)"
time="2025-12-12T19:01:42Z" level=info msg="hub fetch succeeded" endpoint="https://raw.githubusercontent.com/crowdsecurity/hub/master/crowdsecurity/demo.yaml" fallback_used=true
time="2025-12-12T19:01:42Z" level=info msg="storing preset in cache" archive_size=105 etag=etag1 hub_endpoint="https://raw.githubusercontent.com/crowdsecurity/hub/master/crowdsecurity/demo.tgz" preview_size=14 slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestPullFallsBackToMirrorArchiveOnForbidden3050240437/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestPullFallsBackToMirrorArchiveOnForbidden3050240437/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestPullFallsBackToMirrorArchiveOnForbidden3050240437/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="preset successfully cached" archive_path=/tmp/TestPullFallsBackToMirrorArchiveOnForbidden3050240437/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 preview_path=/tmp/TestPullFallsBackToMirrorArchiveOnForbidden3050240437/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
--- PASS: TestPullFallsBackToMirrorArchiveOnForbidden (0.00s)
=== RUN   TestFetchWithLimitRejectsLargePayload
--- PASS: TestFetchWithLimitRejectsLargePayload (0.19s)
=== RUN   TestExtractTarGzRejectsSymlink
--- PASS: TestExtractTarGzRejectsSymlink (0.00s)
=== RUN   TestExtractTarGzRejectsAbsolutePath
--- PASS: TestExtractTarGzRejectsAbsolutePath (0.00s)
=== RUN   TestFetchIndexHTTPError
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=1 error="https://hub-data.crowdsec.net/api/index.json (status 503)" hub_index="https://hub-data.crowdsec.net/api/index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=2 error="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json (status 503)" hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=3 error="https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json (status 503)" hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json"
--- PASS: TestFetchIndexHTTPError (0.00s)
=== RUN   TestPullValidatesSlugAndMissingPreset
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="http://hub.example/api/index.json"
--- PASS: TestPullValidatesSlugAndMissingPreset (0.00s)
=== RUN   TestFetchPreviewRequiresURL
--- PASS: TestFetchPreviewRequiresURL (0.00s)
=== RUN   TestFetchWithLimitRequiresClient
--- PASS: TestFetchWithLimitRequiresClient (0.00s)
=== RUN   TestRunCSCLIRejectsUnsafeSlug
--- PASS: TestRunCSCLIRejectsUnsafeSlug (0.00s)
=== RUN   TestApplyUsesCSCLISuccess
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyUsesCSCLISuccess906171493/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 meta_path=/tmp/TestApplyUsesCSCLISuccess906171493/001/crowdsecurity/demo/metadata.json preview_path=/tmp/TestApplyUsesCSCLISuccess906171493/001/crowdsecurity/demo/preview.yaml slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=info msg="successfully loaded cached preset metadata" archive_path=/tmp/TestApplyUsesCSCLISuccess906171493/001/crowdsecurity/demo/bundle.tgz cache_key=crowdsecurity/demo-1765566102 slug=crowdsecurity/demo
--- PASS: TestApplyUsesCSCLISuccess (0.00s)
=== RUN   TestFetchIndexCSCLIParseError
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=1 error="http://hub.example/api/index.json (status 500)" hub_index="http://hub.example/api/index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=2 error="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json (status 500)" hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=3 error="https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json (status 500)" hub_index="https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json"
time="2025-12-12T19:01:42Z" level=warning msg="hub index fetch failed, trying mirror" attempt=4 error="https://hub-data.crowdsec.net/api/index.json (status 500)" hub_index="https://hub-data.crowdsec.net/api/index.json"
--- PASS: TestFetchIndexCSCLIParseError (0.00s)
=== RUN   TestFetchWithLimitStatusError
--- PASS: TestFetchWithLimitStatusError (0.00s)
=== RUN   TestApplyRollsBackWhenCacheMissing
time="2025-12-12T19:01:42Z" level=error msg="cache unavailable for apply" slug=crowdsecurity/demo
time="2025-12-12T19:01:42Z" level=warning msg="cache refresh failed; rolled back backup" backup_path=/tmp/TestApplyRollsBackWhenCacheMissing1102494851/001/crowdsec.backup.20251212-190142 error="cache unavailable for manual apply" slug=crowdsecurity/demo
--- PASS: TestApplyRollsBackWhenCacheMissing (0.00s)
=== RUN   TestNormalizeHubBaseURL
=== RUN   TestNormalizeHubBaseURL/empty_uses_default
=== RUN   TestNormalizeHubBaseURL/whitespace_uses_default
=== RUN   TestNormalizeHubBaseURL/removes_trailing_slash
=== RUN   TestNormalizeHubBaseURL/removes_multiple_trailing_slashes
=== RUN   TestNormalizeHubBaseURL/trims_spaces
=== RUN   TestNormalizeHubBaseURL/no_slash_unchanged
--- PASS: TestNormalizeHubBaseURL (0.00s)
    --- PASS: TestNormalizeHubBaseURL/empty_uses_default (0.00s)
    --- PASS: TestNormalizeHubBaseURL/whitespace_uses_default (0.00s)
    --- PASS: TestNormalizeHubBaseURL/removes_trailing_slash (0.00s)
    --- PASS: TestNormalizeHubBaseURL/removes_multiple_trailing_slashes (0.00s)
    --- PASS: TestNormalizeHubBaseURL/trims_spaces (0.00s)
    --- PASS: TestNormalizeHubBaseURL/no_slash_unchanged (0.00s)
=== RUN   TestBuildIndexURL
=== RUN   TestBuildIndexURL/empty_base_uses_default
=== RUN   TestBuildIndexURL/standard_base_appends_path
=== RUN   TestBuildIndexURL/trailing_slash_removed
=== RUN   TestBuildIndexURL/direct_json_url_unchanged
=== RUN   TestBuildIndexURL/case_insensitive_json
--- PASS: TestBuildIndexURL (0.00s)
    --- PASS: TestBuildIndexURL/empty_base_uses_default (0.00s)
    --- PASS: TestBuildIndexURL/standard_base_appends_path (0.00s)
    --- PASS: TestBuildIndexURL/trailing_slash_removed (0.00s)
    --- PASS: TestBuildIndexURL/direct_json_url_unchanged (0.00s)
    --- PASS: TestBuildIndexURL/case_insensitive_json (0.00s)
=== RUN   TestUniqueStrings
=== RUN   TestUniqueStrings/empty_slice
=== RUN   TestUniqueStrings/no_duplicates
=== RUN   TestUniqueStrings/with_duplicates
=== RUN   TestUniqueStrings/all_duplicates
=== RUN   TestUniqueStrings/preserves_order
--- PASS: TestUniqueStrings (0.00s)
    --- PASS: TestUniqueStrings/empty_slice (0.00s)
    --- PASS: TestUniqueStrings/no_duplicates (0.00s)
    --- PASS: TestUniqueStrings/with_duplicates (0.00s)
    --- PASS: TestUniqueStrings/all_duplicates (0.00s)
    --- PASS: TestUniqueStrings/preserves_order (0.00s)
=== RUN   TestFirstNonEmpty
=== RUN   TestFirstNonEmpty/first_non-empty
=== RUN   TestFirstNonEmpty/all_empty
=== RUN   TestFirstNonEmpty/first_is_non-empty
=== RUN   TestFirstNonEmpty/whitespace_treated_as_empty
=== RUN   TestFirstNonEmpty/whitespace_with_content
=== RUN   TestFirstNonEmpty/empty_slice
=== RUN   TestFirstNonEmpty/tabs_and_newlines
--- PASS: TestFirstNonEmpty (0.00s)
    --- PASS: TestFirstNonEmpty/first_non-empty (0.00s)
    --- PASS: TestFirstNonEmpty/all_empty (0.00s)
    --- PASS: TestFirstNonEmpty/first_is_non-empty (0.00s)
    --- PASS: TestFirstNonEmpty/whitespace_treated_as_empty (0.00s)
    --- PASS: TestFirstNonEmpty/whitespace_with_content (0.00s)
    --- PASS: TestFirstNonEmpty/empty_slice (0.00s)
    --- PASS: TestFirstNonEmpty/tabs_and_newlines (0.00s)
=== RUN   TestCleanShellArg
=== RUN   TestCleanShellArg/clean_slug
=== RUN   TestCleanShellArg/with_dash
=== RUN   TestCleanShellArg/with_underscore
=== RUN   TestCleanShellArg/with_dot
=== RUN   TestCleanShellArg/path_traversal
=== RUN   TestCleanShellArg/absolute_path
=== RUN   TestCleanShellArg/backslash_converted
=== RUN   TestCleanShellArg/colon_not_allowed
=== RUN   TestCleanShellArg/semicolon
=== RUN   TestCleanShellArg/pipe
=== RUN   TestCleanShellArg/ampersand
=== RUN   TestCleanShellArg/backtick
=== RUN   TestCleanShellArg/dollar
=== RUN   TestCleanShellArg/parenthesis
--- PASS: TestCleanShellArg (0.00s)
    --- PASS: TestCleanShellArg/clean_slug (0.00s)
    --- PASS: TestCleanShellArg/with_dash (0.00s)
    --- PASS: TestCleanShellArg/with_underscore (0.00s)
    --- PASS: TestCleanShellArg/with_dot (0.00s)
    --- PASS: TestCleanShellArg/path_traversal (0.00s)
    --- PASS: TestCleanShellArg/absolute_path (0.00s)
    --- PASS: TestCleanShellArg/backslash_converted (0.00s)
    --- PASS: TestCleanShellArg/colon_not_allowed (0.00s)
    --- PASS: TestCleanShellArg/semicolon (0.00s)
    --- PASS: TestCleanShellArg/pipe (0.00s)
    --- PASS: TestCleanShellArg/ampersand (0.00s)
    --- PASS: TestCleanShellArg/backtick (0.00s)
    --- PASS: TestCleanShellArg/dollar (0.00s)
    --- PASS: TestCleanShellArg/parenthesis (0.00s)
=== RUN   TestHasCSCLI
=== RUN   TestHasCSCLI/cscli_available
=== RUN   TestHasCSCLI/cscli_not_found
--- PASS: TestHasCSCLI (0.00s)
    --- PASS: TestHasCSCLI/cscli_available (0.00s)
    --- PASS: TestHasCSCLI/cscli_not_found (0.00s)
=== RUN   TestFindPreviewFileFromArchive
=== RUN   TestFindPreviewFileFromArchive/finds_yaml_in_archive
=== RUN   TestFindPreviewFileFromArchive/returns_empty_for_no_yaml
=== RUN   TestFindPreviewFileFromArchive/returns_empty_for_invalid_archive
--- PASS: TestFindPreviewFileFromArchive (0.00s)
    --- PASS: TestFindPreviewFileFromArchive/finds_yaml_in_archive (0.00s)
    --- PASS: TestFindPreviewFileFromArchive/returns_empty_for_no_yaml (0.00s)
    --- PASS: TestFindPreviewFileFromArchive/returns_empty_for_invalid_archive (0.00s)
=== RUN   TestApplyWithCopyBasedBackup
time="2025-12-12T19:01:42Z" level=info msg="preset successfully stored in cache" archive_path=/tmp/TestApplyWithCopyBasedBackup4175808900/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 meta_path=/tmp/TestApplyWithCopyBasedBackup4175808900/001/test/preset/metadata.json preview_path=/tmp/TestApplyWithCopyBasedBackup4175808900/001/test/preset/preview.yaml slug=test/preset
time="2025-12-12T19:01:42Z" level=info msg="successfully loaded cached preset metadata" archive_path=/tmp/TestApplyWithCopyBasedBackup4175808900/001/test/preset/bundle.tgz cache_key=test/preset-1765566102 slug=test/preset
--- PASS: TestApplyWithCopyBasedBackup (0.00s)
=== RUN   TestBackupExistingHandlesDeviceBusy
--- PASS: TestBackupExistingHandlesDeviceBusy (0.00s)
=== RUN   TestCopyFile
--- PASS: TestCopyFile (0.01s)
=== RUN   TestCopyDir
--- PASS: TestCopyDir (0.00s)
=== RUN   TestFetchIndexHTTPAcceptsTextPlain
time="2025-12-12T19:01:42Z" level=info msg="hub index fetched" fallback_used=false hub_index="https://hub-data.crowdsec.net/api/index.json"
--- PASS: TestFetchIndexHTTPAcceptsTextPlain (0.00s)
=== RUN   TestEmptyDir
=== RUN   TestEmptyDir/empties_directory_with_files
=== RUN   TestEmptyDir/empties_directory_with_subdirectories
=== RUN   TestEmptyDir/handles_non-existent_directory
=== RUN   TestEmptyDir/handles_empty_directory
--- PASS: TestEmptyDir (0.00s)
    --- PASS: TestEmptyDir/empties_directory_with_files (0.00s)
    --- PASS: TestEmptyDir/empties_directory_with_subdirectories (0.00s)
    --- PASS: TestEmptyDir/handles_non-existent_directory (0.00s)
    --- PASS: TestEmptyDir/handles_empty_directory (0.00s)
=== RUN   TestExtractTarGz
=== RUN   TestExtractTarGz/extracts_valid_archive
=== RUN   TestExtractTarGz/rejects_path_traversal
=== RUN   TestExtractTarGz/rejects_symlinks
=== RUN   TestExtractTarGz/handles_corrupted_gzip
=== RUN   TestExtractTarGz/handles_context_cancellation
=== RUN   TestExtractTarGz/creates_nested_directories
--- PASS: TestExtractTarGz (0.00s)
    --- PASS: TestExtractTarGz/extracts_valid_archive (0.00s)
    --- PASS: TestExtractTarGz/rejects_path_traversal (0.00s)
    --- PASS: TestExtractTarGz/rejects_symlinks (0.00s)
    --- PASS: TestExtractTarGz/handles_corrupted_gzip (0.00s)
    --- PASS: TestExtractTarGz/handles_context_cancellation (0.00s)
    --- PASS: TestExtractTarGz/creates_nested_directories (0.00s)
=== RUN   TestBackupExisting
=== RUN   TestBackupExisting/handles_non-existent_directory
=== RUN   TestBackupExisting/creates_backup_of_existing_directory
=== RUN   TestBackupExisting/backup_contents_match_original
--- PASS: TestBackupExisting (0.00s)
    --- PASS: TestBackupExisting/handles_non-existent_directory (0.00s)
    --- PASS: TestBackupExisting/creates_backup_of_existing_directory (0.00s)
    --- PASS: TestBackupExisting/backup_contents_match_original (0.00s)
=== RUN   TestRollback
=== RUN   TestRollback/rollback_with_backup
=== RUN   TestRollback/rollback_with_empty_backup_path
=== RUN   TestRollback/rollback_with_non-existent_backup
--- PASS: TestRollback (0.00s)
    --- PASS: TestRollback/rollback_with_backup (0.00s)
    --- PASS: TestRollback/rollback_with_empty_backup_path (0.00s)
    --- PASS: TestRollback/rollback_with_non-existent_backup (0.00s)
=== RUN   TestHubHTTPErrorError
=== RUN   TestHubHTTPErrorError/error_with_inner_error
=== RUN   TestHubHTTPErrorError/error_without_inner_error
--- PASS: TestHubHTTPErrorError (0.00s)
    --- PASS: TestHubHTTPErrorError/error_with_inner_error (0.00s)
    --- PASS: TestHubHTTPErrorError/error_without_inner_error (0.00s)
=== RUN   TestHubHTTPErrorUnwrap
=== RUN   TestHubHTTPErrorUnwrap/unwrap_returns_inner_error
=== RUN   TestHubHTTPErrorUnwrap/unwrap_returns_nil_when_no_inner
=== RUN   TestHubHTTPErrorUnwrap/errors.Is_works_through_Unwrap
--- PASS: TestHubHTTPErrorUnwrap (0.00s)
    --- PASS: TestHubHTTPErrorUnwrap/unwrap_returns_inner_error (0.00s)
    --- PASS: TestHubHTTPErrorUnwrap/unwrap_returns_nil_when_no_inner (0.00s)
    --- PASS: TestHubHTTPErrorUnwrap/errors.Is_works_through_Unwrap (0.00s)
=== RUN   TestHubHTTPErrorCanFallback
=== RUN   TestHubHTTPErrorCanFallback/returns_true_when_fallback_is_true
=== RUN   TestHubHTTPErrorCanFallback/returns_false_when_fallback_is_false
--- PASS: TestHubHTTPErrorCanFallback (0.00s)
    --- PASS: TestHubHTTPErrorCanFallback/returns_true_when_fallback_is_true (0.00s)
    --- PASS: TestHubHTTPErrorCanFallback/returns_false_when_fallback_is_false (0.00s)
=== RUN   TestListCuratedPresetsReturnsCopy
--- PASS: TestListCuratedPresetsReturnsCopy (0.00s)
=== RUN   TestFindPreset
--- PASS: TestFindPreset (0.00s)
=== RUN   TestFindPresetCaseVariants
=== RUN   TestFindPresetCaseVariants/exact_match
=== RUN   TestFindPresetCaseVariants/another_preset
=== RUN   TestFindPresetCaseVariants/case_sensitive_miss
=== RUN   TestFindPresetCaseVariants/partial_match_miss
=== RUN   TestFindPresetCaseVariants/empty_slug
--- PASS: TestFindPresetCaseVariants (0.00s)
    --- PASS: TestFindPresetCaseVariants/exact_match (0.00s)
    --- PASS: TestFindPresetCaseVariants/another_preset (0.00s)
    --- PASS: TestFindPresetCaseVariants/case_sensitive_miss (0.00s)
    --- PASS: TestFindPresetCaseVariants/partial_match_miss (0.00s)
    --- PASS: TestFindPresetCaseVariants/empty_slug (0.00s)
=== RUN   TestListCuratedPresetsReturnsDifferentCopy
--- PASS: TestListCuratedPresetsReturnsDifferentCopy (0.00s)
=== RUN   TestCheckLAPIHealth_Healthy
--- PASS: TestCheckLAPIHealth_Healthy (0.00s)
=== RUN   TestCheckLAPIHealth_Unhealthy
--- PASS: TestCheckLAPIHealth_Unhealthy (0.00s)
=== RUN   TestCheckLAPIHealth_Unreachable
--- PASS: TestCheckLAPIHealth_Unreachable (0.00s)
=== RUN   TestCheckLAPIHealth_FallbackToDecisions
--- PASS: TestCheckLAPIHealth_FallbackToDecisions (0.00s)
=== RUN   TestCheckLAPIHealth_DefaultURL
--- PASS: TestCheckLAPIHealth_DefaultURL (0.00s)
=== RUN   TestGetBouncerAPIKey_FromEnv
--- PASS: TestGetBouncerAPIKey_FromEnv (0.00s)
=== RUN   TestGetBouncerAPIKey_Empty
--- PASS: TestGetBouncerAPIKey_Empty (0.00s)
=== RUN   TestGetBouncerAPIKey_Fallback
--- PASS: TestGetBouncerAPIKey_Fallback (0.00s)
=== RUN   TestEnsureBouncerRegistered_UsesEnvKey
--- PASS: TestEnsureBouncerRegistered_UsesEnvKey (0.00s)
=== RUN   TestEnsureBouncerRegistered_NoEnvNoCSCLI
--- PASS: TestEnsureBouncerRegistered_NoEnvNoCSCLI (0.00s)
=== RUN   TestEnsureBouncerRegistered_ReturnsExistingBouncerKey
--- PASS: TestEnsureBouncerRegistered_ReturnsExistingBouncerKey (0.00s)
=== RUN   TestEnsureBouncerRegistered_RegistersNewWhenNoneExists
--- PASS: TestEnsureBouncerRegistered_RegistersNewWhenNoneExists (0.01s)
=== RUN   TestGetLAPIVersion_JSON
--- PASS: TestGetLAPIVersion_JSON (0.00s)
=== RUN   TestGetLAPIVersion_PlainText
--- PASS: TestGetLAPIVersion_PlainText (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/crowdsec	(cached)
=== RUN   TestConnect
--- PASS: TestConnect (0.02s)
=== RUN   TestConnect_Error
--- PASS: TestConnect_Error (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/database	(cached)
=== RUN   TestNewBroadcastHook
--- PASS: TestNewBroadcastHook (0.00s)
=== RUN   TestBroadcastHook_Levels
--- PASS: TestBroadcastHook_Levels (0.00s)
=== RUN   TestBroadcastHook_Subscribe
--- PASS: TestBroadcastHook_Subscribe (0.00s)
=== RUN   TestBroadcastHook_Unsubscribe
--- PASS: TestBroadcastHook_Unsubscribe (0.00s)
=== RUN   TestInit
--- PASS: TestInit (0.00s)
=== RUN   TestLog
--- PASS: TestLog (0.00s)
=== RUN   TestWithFields
--- PASS: TestWithFields (0.00s)
=== RUN   TestBroadcastHook_Fire
--- PASS: TestBroadcastHook_Fire (0.00s)
=== RUN   TestGetBroadcastHook
--- PASS: TestGetBroadcastHook (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/logger	(cached)
=== RUN   TestMetrics_Register
--- PASS: TestMetrics_Register (0.00s)
=== RUN   TestMetrics_Increment
--- PASS: TestMetrics_Increment (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/metrics	(cached)
=== RUN   TestDomain_BeforeCreate
--- PASS: TestDomain_BeforeCreate (0.00s)
=== RUN   TestNotificationTemplate_BeforeCreate
--- PASS: TestNotificationTemplate_BeforeCreate (0.00s)
=== RUN   TestUptimeHost_BeforeCreate
--- PASS: TestUptimeHost_BeforeCreate (0.00s)
=== RUN   TestUptimeNotificationEvent_BeforeCreate
--- PASS: TestUptimeNotificationEvent_BeforeCreate (0.00s)
=== RUN   TestNotification_BeforeCreate
--- PASS: TestNotification_BeforeCreate (0.00s)
=== RUN   TestNotificationConfig_BeforeCreate
--- PASS: TestNotificationConfig_BeforeCreate (0.00s)
=== RUN   TestUser_SetPassword
--- PASS: TestUser_SetPassword (0.27s)
=== RUN   TestUser_CheckPassword
--- PASS: TestUser_CheckPassword (0.18s)
=== RUN   TestUser_HasPendingInvite
=== RUN   TestUser_HasPendingInvite/no_invite_token
=== RUN   TestUser_HasPendingInvite/expired_invite
=== RUN   TestUser_HasPendingInvite/valid_pending_invite
=== RUN   TestUser_HasPendingInvite/already_accepted_invite
--- PASS: TestUser_HasPendingInvite (0.00s)
    --- PASS: TestUser_HasPendingInvite/no_invite_token (0.00s)
    --- PASS: TestUser_HasPendingInvite/expired_invite (0.00s)
    --- PASS: TestUser_HasPendingInvite/valid_pending_invite (0.00s)
    --- PASS: TestUser_HasPendingInvite/already_accepted_invite (0.00s)
=== RUN   TestUser_CanAccessHost_AllowAll
--- PASS: TestUser_CanAccessHost_AllowAll (0.00s)
=== RUN   TestUser_CanAccessHost_DenyAll
--- PASS: TestUser_CanAccessHost_DenyAll (0.00s)
=== RUN   TestUser_CanAccessHost_AdminBypass
--- PASS: TestUser_CanAccessHost_AdminBypass (0.00s)
=== RUN   TestUser_CanAccessHost_DefaultBehavior
--- PASS: TestUser_CanAccessHost_DefaultBehavior (0.00s)
=== RUN   TestUser_CanAccessHost_EmptyPermittedHosts
=== RUN   TestUser_CanAccessHost_EmptyPermittedHosts/allow_all_with_no_exceptions_allows_all
=== RUN   TestUser_CanAccessHost_EmptyPermittedHosts/deny_all_with_no_exceptions_denies_all
--- PASS: TestUser_CanAccessHost_EmptyPermittedHosts (0.00s)
    --- PASS: TestUser_CanAccessHost_EmptyPermittedHosts/allow_all_with_no_exceptions_allows_all (0.00s)
    --- PASS: TestUser_CanAccessHost_EmptyPermittedHosts/deny_all_with_no_exceptions_denies_all (0.00s)
=== RUN   TestPermissionMode_Constants
--- PASS: TestPermissionMode_Constants (0.00s)
=== RUN   TestNotificationProvider_BeforeCreate
--- PASS: TestNotificationProvider_BeforeCreate (0.00s)
=== RUN   TestUptimeMonitor_BeforeCreate
--- PASS: TestUptimeMonitor_BeforeCreate (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/models	(cached)
=== RUN   TestNewRouter
[GIN] 2025/12/12 - 00:34:55 | 200 |    1.889348ms |                 | GET      "/"
--- PASS: TestNewRouter (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/server	(cached)
=== RUN   TestAccessListService_Create
=== RUN   TestAccessListService_Create/create_whitelist_with_valid_IP_rules
=== RUN   TestAccessListService_Create/create_geo_whitelist_with_valid_country_codes
=== RUN   TestAccessListService_Create/create_local_network_only_ACL
=== RUN   TestAccessListService_Create/fail_with_empty_name
=== RUN   TestAccessListService_Create/fail_with_invalid_type
=== RUN   TestAccessListService_Create/fail_with_invalid_IP_address
=== RUN   TestAccessListService_Create/fail_geo-blocking_without_country_codes
=== RUN   TestAccessListService_Create/fail_with_invalid_country_code
--- PASS: TestAccessListService_Create (0.00s)
    --- PASS: TestAccessListService_Create/create_whitelist_with_valid_IP_rules (0.00s)
    --- PASS: TestAccessListService_Create/create_geo_whitelist_with_valid_country_codes (0.00s)
    --- PASS: TestAccessListService_Create/create_local_network_only_ACL (0.00s)
    --- PASS: TestAccessListService_Create/fail_with_empty_name (0.00s)
    --- PASS: TestAccessListService_Create/fail_with_invalid_type (0.00s)
    --- PASS: TestAccessListService_Create/fail_with_invalid_IP_address (0.00s)
    --- PASS: TestAccessListService_Create/fail_geo-blocking_without_country_codes (0.00s)
    --- PASS: TestAccessListService_Create/fail_with_invalid_country_code (0.00s)
=== RUN   TestAccessListService_GetByID
=== RUN   TestAccessListService_GetByID/get_existing_ACL
=== RUN   TestAccessListService_GetByID/get_non-existent_ACL

2025/12/12 19:01:44 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 99999 ORDER BY `access_lists`.`id` LIMIT 1
--- PASS: TestAccessListService_GetByID (0.00s)
    --- PASS: TestAccessListService_GetByID/get_existing_ACL (0.00s)
    --- PASS: TestAccessListService_GetByID/get_non-existent_ACL (0.00s)
=== RUN   TestAccessListService_GetByUUID
=== RUN   TestAccessListService_GetByUUID/get_existing_ACL_by_UUID
=== RUN   TestAccessListService_GetByUUID/get_non-existent_ACL_by_UUID

2025/12/12 19:01:44 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:117 [35;1mrecord not found
[0m[33m[0.046ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE uuid = "non-existent-uuid" ORDER BY `access_lists`.`id` LIMIT 1
--- PASS: TestAccessListService_GetByUUID (0.00s)
    --- PASS: TestAccessListService_GetByUUID/get_existing_ACL_by_UUID (0.00s)
    --- PASS: TestAccessListService_GetByUUID/get_non-existent_ACL_by_UUID (0.00s)
=== RUN   TestAccessListService_List
=== RUN   TestAccessListService_List/list_all_ACLs
--- PASS: TestAccessListService_List (0.00s)
    --- PASS: TestAccessListService_List/list_all_ACLs (0.00s)
=== RUN   TestAccessListService_Update
=== RUN   TestAccessListService_Update/update_successfully
=== RUN   TestAccessListService_Update/fail_update_on_non-existent_ACL

2025/12/12 19:01:44 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 99999 ORDER BY `access_lists`.`id` LIMIT 1
=== RUN   TestAccessListService_Update/fail_update_with_invalid_data
--- PASS: TestAccessListService_Update (0.00s)
    --- PASS: TestAccessListService_Update/update_successfully (0.00s)
    --- PASS: TestAccessListService_Update/fail_update_on_non-existent_ACL (0.00s)
    --- PASS: TestAccessListService_Update/fail_update_with_invalid_data (0.00s)
=== RUN   TestAccessListService_Delete
=== RUN   TestAccessListService_Delete/delete_successfully

2025/12/12 19:01:44 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mrecord not found
[0m[33m[0.059ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 1 ORDER BY `access_lists`.`id` LIMIT 1
=== RUN   TestAccessListService_Delete/fail_delete_non-existent_ACL
=== RUN   TestAccessListService_Delete/fail_delete_ACL_in_use
--- PASS: TestAccessListService_Delete (0.00s)
    --- PASS: TestAccessListService_Delete/delete_successfully (0.00s)
    --- PASS: TestAccessListService_Delete/fail_delete_non-existent_ACL (0.00s)
    --- PASS: TestAccessListService_Delete/fail_delete_ACL_in_use (0.00s)
=== RUN   TestAccessListService_TestIP
=== RUN   TestAccessListService_TestIP/whitelist_allows_matching_IP
=== RUN   TestAccessListService_TestIP/whitelist_blocks_non-matching_IP
=== RUN   TestAccessListService_TestIP/blacklist_blocks_matching_IP
=== RUN   TestAccessListService_TestIP/blacklist_allows_non-matching_IP
=== RUN   TestAccessListService_TestIP/local_network_only_allows_RFC1918
=== RUN   TestAccessListService_TestIP/disabled_ACL_allows_all
=== RUN   TestAccessListService_TestIP/fail_with_invalid_IP
--- PASS: TestAccessListService_TestIP (0.00s)
    --- PASS: TestAccessListService_TestIP/whitelist_allows_matching_IP (0.00s)
    --- PASS: TestAccessListService_TestIP/whitelist_blocks_non-matching_IP (0.00s)
    --- PASS: TestAccessListService_TestIP/blacklist_blocks_matching_IP (0.00s)
    --- PASS: TestAccessListService_TestIP/blacklist_allows_non-matching_IP (0.00s)
    --- PASS: TestAccessListService_TestIP/local_network_only_allows_RFC1918 (0.00s)
    --- PASS: TestAccessListService_TestIP/disabled_ACL_allows_all (0.00s)
    --- PASS: TestAccessListService_TestIP/fail_with_invalid_IP (0.00s)
=== RUN   TestAccessListService_GetTemplates
--- PASS: TestAccessListService_GetTemplates (0.00s)
=== RUN   TestAccessListService_Validation
=== RUN   TestAccessListService_Validation/validate_CIDR_formats
=== RUN   TestAccessListService_Validation/validate_country_codes
=== RUN   TestAccessListService_Validation/validate_types
--- PASS: TestAccessListService_Validation (0.00s)
    --- PASS: TestAccessListService_Validation/validate_CIDR_formats (0.00s)
    --- PASS: TestAccessListService_Validation/validate_country_codes (0.00s)
    --- PASS: TestAccessListService_Validation/validate_types (0.00s)
=== RUN   TestIPMatchesCIDR_Helper
=== RUN   TestIPMatchesCIDR_Helper/IPv4_in_subnet
=== RUN   TestIPMatchesCIDR_Helper/IPv4_not_in_subnet
=== RUN   TestIPMatchesCIDR_Helper/IPv4_single_IP_match
=== RUN   TestIPMatchesCIDR_Helper/IPv4_single_IP_no_match
=== RUN   TestIPMatchesCIDR_Helper/IPv6_in_subnet
=== RUN   TestIPMatchesCIDR_Helper/IPv6_not_in_subnet
=== RUN   TestIPMatchesCIDR_Helper/Invalid_CIDR
--- PASS: TestIPMatchesCIDR_Helper (0.00s)
    --- PASS: TestIPMatchesCIDR_Helper/IPv4_in_subnet (0.00s)
    --- PASS: TestIPMatchesCIDR_Helper/IPv4_not_in_subnet (0.00s)
    --- PASS: TestIPMatchesCIDR_Helper/IPv4_single_IP_match (0.00s)
    --- PASS: TestIPMatchesCIDR_Helper/IPv4_single_IP_no_match (0.00s)
    --- PASS: TestIPMatchesCIDR_Helper/IPv6_in_subnet (0.00s)
    --- PASS: TestIPMatchesCIDR_Helper/IPv6_not_in_subnet (0.00s)
    --- PASS: TestIPMatchesCIDR_Helper/Invalid_CIDR (0.00s)
=== RUN   TestIsPrivateIP_Helper
=== RUN   TestIsPrivateIP_Helper/Private_10.x.x.x
=== RUN   TestIsPrivateIP_Helper/Private_172.16.x.x
=== RUN   TestIsPrivateIP_Helper/Private_192.168.x.x
=== RUN   TestIsPrivateIP_Helper/Private_127.0.0.1
=== RUN   TestIsPrivateIP_Helper/Private_::1
=== RUN   TestIsPrivateIP_Helper/Private_fc00::/7
=== RUN   TestIsPrivateIP_Helper/Public_8.8.8.8
=== RUN   TestIsPrivateIP_Helper/Public_1.1.1.1
=== RUN   TestIsPrivateIP_Helper/Public_IPv6
--- PASS: TestIsPrivateIP_Helper (0.00s)
    --- PASS: TestIsPrivateIP_Helper/Private_10.x.x.x (0.00s)
    --- PASS: TestIsPrivateIP_Helper/Private_172.16.x.x (0.00s)
    --- PASS: TestIsPrivateIP_Helper/Private_192.168.x.x (0.00s)
    --- PASS: TestIsPrivateIP_Helper/Private_127.0.0.1 (0.00s)
    --- PASS: TestIsPrivateIP_Helper/Private_::1 (0.00s)
    --- PASS: TestIsPrivateIP_Helper/Private_fc00::/7 (0.00s)
    --- PASS: TestIsPrivateIP_Helper/Public_8.8.8.8 (0.00s)
    --- PASS: TestIsPrivateIP_Helper/Public_1.1.1.1 (0.00s)
    --- PASS: TestIsPrivateIP_Helper/Public_IPv6 (0.00s)
=== RUN   TestAccessListService_ListFunction
--- PASS: TestAccessListService_ListFunction (0.00s)
=== RUN   TestAccessListService_SetGeoIPService
--- PASS: TestAccessListService_SetGeoIPService (0.00s)
=== RUN   TestAccessListService_GeoACL_NoGeoIPService
=== RUN   TestAccessListService_GeoACL_NoGeoIPService/geo_whitelist_without_GeoIP_service_allows_traffic
=== RUN   TestAccessListService_GeoACL_NoGeoIPService/geo_blacklist_without_GeoIP_service_allows_traffic
--- PASS: TestAccessListService_GeoACL_NoGeoIPService (0.00s)
    --- PASS: TestAccessListService_GeoACL_NoGeoIPService/geo_whitelist_without_GeoIP_service_allows_traffic (0.00s)
    --- PASS: TestAccessListService_GeoACL_NoGeoIPService/geo_blacklist_without_GeoIP_service_allows_traffic (0.00s)
=== RUN   TestAccessListService_ParseCountryCodes
=== RUN   TestAccessListService_ParseCountryCodes/parse_single_code
=== RUN   TestAccessListService_ParseCountryCodes/parse_multiple_codes
=== RUN   TestAccessListService_ParseCountryCodes/parse_with_spaces
=== RUN   TestAccessListService_ParseCountryCodes/parse_with_lowercase
=== RUN   TestAccessListService_ParseCountryCodes/parse_empty_string
=== RUN   TestAccessListService_ParseCountryCodes/parse_with_empty_entries
--- PASS: TestAccessListService_ParseCountryCodes (0.00s)
    --- PASS: TestAccessListService_ParseCountryCodes/parse_single_code (0.00s)
    --- PASS: TestAccessListService_ParseCountryCodes/parse_multiple_codes (0.00s)
    --- PASS: TestAccessListService_ParseCountryCodes/parse_with_spaces (0.00s)
    --- PASS: TestAccessListService_ParseCountryCodes/parse_with_lowercase (0.00s)
    --- PASS: TestAccessListService_ParseCountryCodes/parse_empty_string (0.00s)
    --- PASS: TestAccessListService_ParseCountryCodes/parse_with_empty_entries (0.00s)
=== RUN   TestAuthService_Register
--- PASS: TestAuthService_Register (0.12s)
=== RUN   TestAuthService_Login
--- PASS: TestAuthService_Login (0.42s)
=== RUN   TestAuthService_ChangePassword

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/auth_service.go:113 [35;1mrecord not found
[0m[33m[0.200ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestAuthService_ChangePassword (0.36s)
=== RUN   TestAuthService_ValidateToken
--- PASS: TestAuthService_ValidateToken (0.12s)
=== RUN   TestAuthService_GetUserByID

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/auth_service.go:147 [35;1mrecord not found
[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
--- PASS: TestAuthService_GetUserByID (0.06s)
=== RUN   TestBackupService_GetAvailableSpace
=== PAUSE TestBackupService_GetAvailableSpace
=== RUN   TestBackupService_CreateAndList
--- PASS: TestBackupService_CreateAndList (0.00s)
=== RUN   TestBackupService_Restore_ZipSlip
--- PASS: TestBackupService_Restore_ZipSlip (0.00s)
=== RUN   TestBackupService_PathTraversal
--- PASS: TestBackupService_PathTraversal (0.00s)
=== RUN   TestBackupService_RunScheduledBackup
time="2025-12-12T19:01:45Z" level=info msg="Starting scheduled backup"
time="2025-12-12T19:01:45Z" level=warning msg="Warning: could not backup caddy dir" error="lstat /tmp/TestBackupService_RunScheduledBackup2081147944/001/data/caddy: no such file or directory"
time="2025-12-12T19:01:45Z" level=info msg="Scheduled backup created" backup=backup_2025-12-12_19-01-45.zip
--- PASS: TestBackupService_RunScheduledBackup (0.00s)
=== RUN   TestBackupService_CreateBackup_Errors
=== RUN   TestBackupService_CreateBackup_Errors/missing_database_file
=== RUN   TestBackupService_CreateBackup_Errors/cannot_create_backup_directory
--- PASS: TestBackupService_CreateBackup_Errors (0.00s)
    --- PASS: TestBackupService_CreateBackup_Errors/missing_database_file (0.00s)
    --- PASS: TestBackupService_CreateBackup_Errors/cannot_create_backup_directory (0.00s)
=== RUN   TestBackupService_RestoreBackup_Errors
=== RUN   TestBackupService_RestoreBackup_Errors/non-existent_backup
=== RUN   TestBackupService_RestoreBackup_Errors/invalid_zip_file
--- PASS: TestBackupService_RestoreBackup_Errors (0.00s)
    --- PASS: TestBackupService_RestoreBackup_Errors/non-existent_backup (0.00s)
    --- PASS: TestBackupService_RestoreBackup_Errors/invalid_zip_file (0.00s)
=== RUN   TestBackupService_ListBackups_EmptyDir
--- PASS: TestBackupService_ListBackups_EmptyDir (0.00s)
=== RUN   TestBackupService_ListBackups_MissingDir
--- PASS: TestBackupService_ListBackups_MissingDir (0.00s)
=== RUN   TestNewCertificateService
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestNewCertificateService2961672703/001/certificates
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=0
--- PASS: TestNewCertificateService (0.10s)
=== RUN   TestCertificateService_GetCertificateInfo
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/cert-test277269634/certificates

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.152ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.255ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=1
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/cert-test277269634/certificates

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "expired.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=2
--- PASS: TestCertificateService_GetCertificateInfo (0.13s)
=== RUN   TestCertificateService_UploadAndDelete
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_UploadAndDelete1997251663/001/certificates
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: cert directory does not exist" certRoot=/tmp/TestCertificateService_UploadAndDelete1997251663/001/certificates
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=1
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_UploadAndDelete1997251663/001/certificates
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: cert directory does not exist" certRoot=/tmp/TestCertificateService_UploadAndDelete1997251663/001/certificates
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=0
--- PASS: TestCertificateService_UploadAndDelete (0.16s)
=== RUN   TestCertificateService_Persistence
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_Persistence800545086/001/certificates

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.144ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "persist.example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=1
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: deleting ACME cert file" path=/tmp/TestCertificateService_Persistence800545086/001/certificates/acme-v02.api.letsencrypt.org-directory/persist.example.com/persist.example.com.crt
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_Persistence800545086/001/certificates
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=0

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/certificate_service_test.go:289 [35;1mrecord not found
[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE (domains = "persist.example.com" AND provider = "letsencrypt") AND `ssl_certificates`.`id` = 1 ORDER BY `ssl_certificates`.`id` LIMIT 1
--- PASS: TestCertificateService_Persistence (0.04s)
=== RUN   TestCertificateService_UploadCertificate_Errors
=== RUN   TestCertificateService_UploadCertificate_Errors/invalid_PEM_format
=== RUN   TestCertificateService_UploadCertificate_Errors/empty_certificate
=== RUN   TestCertificateService_UploadCertificate_Errors/certificate_without_key_allowed
=== RUN   TestCertificateService_UploadCertificate_Errors/valid_certificate_with_name
=== RUN   TestCertificateService_UploadCertificate_Errors/expired_certificate_can_be_uploaded
--- PASS: TestCertificateService_UploadCertificate_Errors (0.14s)
    --- PASS: TestCertificateService_UploadCertificate_Errors/invalid_PEM_format (0.00s)
    --- PASS: TestCertificateService_UploadCertificate_Errors/empty_certificate (0.00s)
    --- PASS: TestCertificateService_UploadCertificate_Errors/certificate_without_key_allowed (0.03s)
    --- PASS: TestCertificateService_UploadCertificate_Errors/valid_certificate_with_name (0.04s)
    --- PASS: TestCertificateService_UploadCertificate_Errors/expired_certificate_can_be_uploaded (0.07s)
=== RUN   TestCertificateService_ListCertificates_EdgeCases
=== RUN   TestCertificateService_ListCertificates_EdgeCases/empty_certificates_directory
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_ListCertificates_EdgeCasesempty_certific1812970575/001/certificates
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: cert directory does not exist" certRoot=/tmp/TestCertificateService_ListCertificates_EdgeCasesempty_certific1812970575/001/certificates

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.227ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=0
=== RUN   TestCertificateService_ListCertificates_EdgeCases/certificates_directory_does_not_exist
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_ListCertificates_EdgeCasescertificates_d9819933/001/does-not-exist/certificates
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: cert directory does not exist" certRoot=/tmp/TestCertificateService_ListCertificates_EdgeCasescertificates_d9819933/001/does-not-exist/certificates

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.204ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=0
=== RUN   TestCertificateService_ListCertificates_EdgeCases/invalid_certificate_files_are_skipped
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_ListCertificates_EdgeCasesinvalid_certif4204332528/001/certificates

2025/12/12 19:01:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.161ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:45Z" level=info msg="CertificateService: disk sync complete" count=0
=== RUN   TestCertificateService_ListCertificates_EdgeCases/multiple_certificates_from_different_providers
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_ListCertificates_EdgeCasesmultiple_certi2309667957/001/certificates

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.065ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "le.example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.265ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=2
--- PASS: TestCertificateService_ListCertificates_EdgeCases (0.21s)
    --- PASS: TestCertificateService_ListCertificates_EdgeCases/empty_certificates_directory (0.00s)
    --- PASS: TestCertificateService_ListCertificates_EdgeCases/certificates_directory_does_not_exist (0.00s)
    --- PASS: TestCertificateService_ListCertificates_EdgeCases/invalid_certificate_files_are_skipped (0.00s)
    --- PASS: TestCertificateService_ListCertificates_EdgeCases/multiple_certificates_from_different_providers (0.21s)
=== RUN   TestCertificateService_DeleteCertificate_Errors
=== RUN   TestCertificateService_DeleteCertificate_Errors/delete_non-existent_certificate

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:410 [35;1mrecord not found
[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE `ssl_certificates`.`id` = 99999 ORDER BY `ssl_certificates`.`id` LIMIT 1
=== RUN   TestCertificateService_DeleteCertificate_Errors/delete_certificate_in_use_returns_ErrCertInUse
=== RUN   TestCertificateService_DeleteCertificate_Errors/delete_certificate_when_file_already_removed

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service_test.go:513 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE id = 2 ORDER BY `ssl_certificates`.`id` LIMIT 1
--- PASS: TestCertificateService_DeleteCertificate_Errors (0.07s)
    --- PASS: TestCertificateService_DeleteCertificate_Errors/delete_non-existent_certificate (0.00s)
    --- PASS: TestCertificateService_DeleteCertificate_Errors/delete_certificate_in_use_returns_ErrCertInUse (0.04s)
    --- PASS: TestCertificateService_DeleteCertificate_Errors/delete_certificate_when_file_already_removed (0.03s)
=== RUN   TestCertificateService_StagingCertificates
=== RUN   TestCertificateService_StagingCertificates/staging_certificate_detected_by_path
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_StagingCertificatesstaging_certificate_d3028211653/001/certificates

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.183ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "staging.example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.318ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=1
=== RUN   TestCertificateService_StagingCertificates/production_cert_preferred_over_staging
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_StagingCertificatesproduction_cert_prefe589373168/001/certificates

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.135ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "both.example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.251ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=1
=== RUN   TestCertificateService_StagingCertificates/upgrade_from_staging_to_production
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_StagingCertificatesupgrade_from_staging_992636313/001/certificates

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.130ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "upgrade.example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.270ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=1
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_StagingCertificatesupgrade_from_staging_992636313/001/certificates

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=1
--- PASS: TestCertificateService_StagingCertificates (0.21s)
    --- PASS: TestCertificateService_StagingCertificates/staging_certificate_detected_by_path (0.13s)
    --- PASS: TestCertificateService_StagingCertificates/production_cert_preferred_over_staging (0.03s)
    --- PASS: TestCertificateService_StagingCertificates/upgrade_from_staging_to_production (0.05s)
=== RUN   TestCertificateService_ExpiringStatus
=== RUN   TestCertificateService_ExpiringStatus/certificate_expiring_within_30_days
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_ExpiringStatuscertificate_expiring_withi2043074678/001/certificates

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.115ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "expiring.example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.289ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=1
=== RUN   TestCertificateService_ExpiringStatus/certificate_valid_for_more_than_30_days
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_ExpiringStatuscertificate_valid_for_more411978940/001/certificates

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.142ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "valid-long.example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.319ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=1
=== RUN   TestCertificateService_ExpiringStatus/staging_cert_always_untrusted_even_if_expiring
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_ExpiringStatusstaging_cert_always_untrus1680907044/001/certificates

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.163ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "staging-expiring.example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.344ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=1
--- PASS: TestCertificateService_ExpiringStatus (0.24s)
    --- PASS: TestCertificateService_ExpiringStatus/certificate_expiring_within_30_days (0.05s)
    --- PASS: TestCertificateService_ExpiringStatus/certificate_valid_for_more_than_30_days (0.09s)
    --- PASS: TestCertificateService_ExpiringStatus/staging_cert_always_untrusted_even_if_expiring (0.10s)
=== RUN   TestCertificateService_StaleCertCleanup
=== RUN   TestCertificateService_StaleCertCleanup/stale_DB_entries_removed_when_file_deleted
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_StaleCertCleanupstale_DB_entries_removed416459177/001/certificates

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:123 [35;1mrecord not found
[0m[33m[0.121ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE domains = "stale.example.com" ORDER BY `ssl_certificates`.`id` LIMIT 1

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.282ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=1
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_StaleCertCleanupstale_DB_entries_removed416459177/001/certificates
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: removed stale DB cert" domain=stale.example.com

2025/12/12 19:01:46 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:46Z" level=info msg="CertificateService: disk sync complete" count=0
--- PASS: TestCertificateService_StaleCertCleanup (0.14s)
    --- PASS: TestCertificateService_StaleCertCleanup/stale_DB_entries_removed_when_file_deleted (0.14s)
=== RUN   TestCertificateService_CertificateWithSANs
=== RUN   TestCertificateService_CertificateWithSANs/certificate_with_SANs_uses_joined_domains
--- PASS: TestCertificateService_CertificateWithSANs (0.17s)
    --- PASS: TestCertificateService_CertificateWithSANs/certificate_with_SANs_uses_joined_domains (0.17s)
=== RUN   TestCertificateService_IsCertificateInUse
=== RUN   TestCertificateService_IsCertificateInUse/certificate_not_in_use
=== RUN   TestCertificateService_IsCertificateInUse/certificate_used_by_one_proxy_host
=== RUN   TestCertificateService_IsCertificateInUse/certificate_used_by_multiple_proxy_hosts
=== RUN   TestCertificateService_IsCertificateInUse/non-existent_certificate
=== RUN   TestCertificateService_IsCertificateInUse/certificate_freed_after_proxy_host_deletion
--- PASS: TestCertificateService_IsCertificateInUse (0.18s)
    --- PASS: TestCertificateService_IsCertificateInUse/certificate_not_in_use (0.02s)
    --- PASS: TestCertificateService_IsCertificateInUse/certificate_used_by_one_proxy_host (0.03s)
    --- PASS: TestCertificateService_IsCertificateInUse/certificate_used_by_multiple_proxy_hosts (0.01s)
    --- PASS: TestCertificateService_IsCertificateInUse/non-existent_certificate (0.00s)
    --- PASS: TestCertificateService_IsCertificateInUse/certificate_freed_after_proxy_host_deletion (0.11s)
=== RUN   TestCertificateService_CacheBehavior
=== RUN   TestCertificateService_CacheBehavior/cache_returns_consistent_results
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_CacheBehaviorcache_returns_consistent_re689688188/001/certificates
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: cert directory does not exist" certRoot=/tmp/TestCertificateService_CacheBehaviorcache_returns_consistent_re689688188/001/certificates

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.256ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: disk sync complete" count=1
=== RUN   TestCertificateService_CacheBehavior/invalidate_cache_forces_resync
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_CacheBehaviorinvalidate_cache_forces_res1008682794/001/certificates
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: cert directory does not exist" certRoot=/tmp/TestCertificateService_CacheBehaviorinvalidate_cache_forces_res1008682794/001/certificates

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.796ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: disk sync complete" count=1
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_CacheBehaviorinvalidate_cache_forces_res1008682794/001/certificates
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: cert directory does not exist" certRoot=/tmp/TestCertificateService_CacheBehaviorinvalidate_cache_forces_res1008682794/001/certificates

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: disk sync complete" count=2
=== RUN   TestCertificateService_CacheBehavior/refreshCacheFromDB_used_when_directory_nonexistent
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: scanning cert directory" certRoot=/tmp/TestCertificateService_CacheBehaviorrefreshCacheFromDB_used_whe2455254220/001/nonexistent/certificates
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: cert directory does not exist" certRoot=/tmp/TestCertificateService_CacheBehaviorrefreshCacheFromDB_used_whe2455254220/001/nonexistent/certificates

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
[0m[33m[0.260ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
time="2025-12-12T19:01:47Z" level=info msg="CertificateService: disk sync complete" count=1
--- PASS: TestCertificateService_CacheBehavior (0.08s)
    --- PASS: TestCertificateService_CacheBehavior/cache_returns_consistent_results (0.03s)
    --- PASS: TestCertificateService_CacheBehavior/invalidate_cache_forces_resync (0.05s)
    --- PASS: TestCertificateService_CacheBehavior/refreshCacheFromDB_used_when_directory_nonexistent (0.00s)
=== RUN   TestDockerService_New
--- PASS: TestDockerService_New (0.00s)
=== RUN   TestDockerService_ListContainers
--- PASS: TestDockerService_ListContainers (0.00s)
=== RUN   TestNewGeoIPService_InvalidPath
--- PASS: TestNewGeoIPService_InvalidPath (0.00s)
=== RUN   TestGeoIPService_NotLoaded
--- PASS: TestGeoIPService_NotLoaded (0.00s)
=== RUN   TestGeoIPService_InvalidIP
--- PASS: TestGeoIPService_InvalidIP (0.00s)
=== RUN   TestGeoIPService_LookupCountry_CountryNotFound
--- PASS: TestGeoIPService_LookupCountry_CountryNotFound (0.00s)
=== RUN   TestGeoIPService_LookupCountry_Success
--- PASS: TestGeoIPService_LookupCountry_Success (0.00s)
=== RUN   TestGeoIPService_LookupCountry_ReaderError
--- PASS: TestGeoIPService_LookupCountry_ReaderError (0.00s)
=== RUN   TestGeoIPService_Close
--- PASS: TestGeoIPService_Close (0.00s)
=== RUN   TestGeoIPService_GetDatabasePath
--- PASS: TestGeoIPService_GetDatabasePath (0.00s)
=== RUN   TestGeoIPService_ConcurrentAccess
--- PASS: TestGeoIPService_ConcurrentAccess (0.00s)
=== RUN   TestGeoIPService_Integration
    geoip_service_test.go:134: GeoIP database not found, skipping integration test
--- SKIP: TestGeoIPService_Integration (0.00s)
=== RUN   TestGeoIPService_ErrorTypes
--- PASS: TestGeoIPService_ErrorTypes (0.00s)
=== RUN   TestLogService
--- PASS: TestLogService (0.00s)
=== RUN   TestMailService_SaveAndGetSMTPConfig
--- PASS: TestMailService_SaveAndGetSMTPConfig (0.00s)
=== RUN   TestMailService_UpdateSMTPConfig
--- PASS: TestMailService_UpdateSMTPConfig (0.00s)
=== RUN   TestMailService_IsConfigured
=== RUN   TestMailService_IsConfigured/configured_with_all_fields
=== RUN   TestMailService_IsConfigured/not_configured_-_missing_host
=== RUN   TestMailService_IsConfigured/not_configured_-_missing_from_address
--- PASS: TestMailService_IsConfigured (0.00s)
    --- PASS: TestMailService_IsConfigured/configured_with_all_fields (0.00s)
    --- PASS: TestMailService_IsConfigured/not_configured_-_missing_host (0.00s)
    --- PASS: TestMailService_IsConfigured/not_configured_-_missing_from_address (0.00s)
=== RUN   TestMailService_GetSMTPConfig_Defaults
--- PASS: TestMailService_GetSMTPConfig_Defaults (0.00s)
=== RUN   TestMailService_BuildEmail
--- PASS: TestMailService_BuildEmail (0.00s)
=== RUN   TestMailService_HeaderInjectionPrevention
=== RUN   TestMailService_HeaderInjectionPrevention/subject_with_CRLF_injection_attempt
=== RUN   TestMailService_HeaderInjectionPrevention/subject_with_LF_injection_attempt
=== RUN   TestMailService_HeaderInjectionPrevention/subject_with_null_byte
--- PASS: TestMailService_HeaderInjectionPrevention (0.00s)
    --- PASS: TestMailService_HeaderInjectionPrevention/subject_with_CRLF_injection_attempt (0.00s)
    --- PASS: TestMailService_HeaderInjectionPrevention/subject_with_LF_injection_attempt (0.00s)
    --- PASS: TestMailService_HeaderInjectionPrevention/subject_with_null_byte (0.00s)
=== RUN   TestSanitizeEmailHeader
=== RUN   TestSanitizeEmailHeader/clean_string
=== RUN   TestSanitizeEmailHeader/CR_removal
=== RUN   TestSanitizeEmailHeader/LF_removal
=== RUN   TestSanitizeEmailHeader/CRLF_removal
=== RUN   TestSanitizeEmailHeader/null_byte_removal
=== RUN   TestSanitizeEmailHeader/tab_removal
=== RUN   TestSanitizeEmailHeader/multiple_control_chars
=== RUN   TestSanitizeEmailHeader/empty_string
--- PASS: TestSanitizeEmailHeader (0.00s)
    --- PASS: TestSanitizeEmailHeader/clean_string (0.00s)
    --- PASS: TestSanitizeEmailHeader/CR_removal (0.00s)
    --- PASS: TestSanitizeEmailHeader/LF_removal (0.00s)
    --- PASS: TestSanitizeEmailHeader/CRLF_removal (0.00s)
    --- PASS: TestSanitizeEmailHeader/null_byte_removal (0.00s)
    --- PASS: TestSanitizeEmailHeader/tab_removal (0.00s)
    --- PASS: TestSanitizeEmailHeader/multiple_control_chars (0.00s)
    --- PASS: TestSanitizeEmailHeader/empty_string (0.00s)
=== RUN   TestValidateEmailAddress
=== RUN   TestValidateEmailAddress/valid_email
=== RUN   TestValidateEmailAddress/valid_email_with_name
=== RUN   TestValidateEmailAddress/empty_email
=== RUN   TestValidateEmailAddress/invalid_format
=== RUN   TestValidateEmailAddress/missing_domain
=== RUN   TestValidateEmailAddress/injection_attempt
--- PASS: TestValidateEmailAddress (0.00s)
    --- PASS: TestValidateEmailAddress/valid_email (0.00s)
    --- PASS: TestValidateEmailAddress/valid_email_with_name (0.00s)
    --- PASS: TestValidateEmailAddress/empty_email (0.00s)
    --- PASS: TestValidateEmailAddress/invalid_format (0.00s)
    --- PASS: TestValidateEmailAddress/missing_domain (0.00s)
    --- PASS: TestValidateEmailAddress/injection_attempt (0.00s)
=== RUN   TestMailService_TestConnection_NotConfigured
--- PASS: TestMailService_TestConnection_NotConfigured (0.00s)
=== RUN   TestMailService_SendEmail_NotConfigured
--- PASS: TestMailService_SendEmail_NotConfigured (0.00s)
=== RUN   TestSMTPConfigSerialization
--- PASS: TestSMTPConfigSerialization (0.00s)
=== RUN   TestMailService_SendInvite_Template
time="2025-12-12T19:01:47Z" level=info msg="Sending invite email" email=test@example.com
--- PASS: TestMailService_SendInvite_Template (0.00s)
=== RUN   TestMailService_Integration
    mail_service_test.go:383: Integration test requires SMTP server
--- SKIP: TestMailService_Integration (0.00s)
=== RUN   TestMailService_SendInvite_TokenFormat
time="2025-12-12T19:01:47Z" level=info msg="Sending invite email" email=test@example.com
time="2025-12-12T19:01:47Z" level=info msg="Sending invite email" email=test@example.com
--- PASS: TestMailService_SendInvite_TokenFormat (0.01s)
=== RUN   TestMailService_SaveSMTPConfig_Concurrent
    mail_service_test.go:412: In-memory SQLite doesn't support concurrent writes - test real DB in integration
--- SKIP: TestMailService_SaveSMTPConfig_Concurrent (0.00s)
=== RUN   TestMailService_SendEmail_InvalidRecipient
--- PASS: TestMailService_SendEmail_InvalidRecipient (0.00s)
=== RUN   TestMailService_SendEmail_InvalidFromAddress
--- PASS: TestMailService_SendEmail_InvalidFromAddress (0.00s)
=== RUN   TestMailService_SendEmail_EncryptionModes
=== RUN   TestMailService_SendEmail_EncryptionModes/ssl
=== RUN   TestMailService_SendEmail_EncryptionModes/starttls
=== RUN   TestMailService_SendEmail_EncryptionModes/none
=== RUN   TestMailService_SendEmail_EncryptionModes/empty
--- PASS: TestMailService_SendEmail_EncryptionModes (0.01s)
    --- PASS: TestMailService_SendEmail_EncryptionModes/ssl (0.00s)
    --- PASS: TestMailService_SendEmail_EncryptionModes/starttls (0.00s)
    --- PASS: TestMailService_SendEmail_EncryptionModes/none (0.00s)
    --- PASS: TestMailService_SendEmail_EncryptionModes/empty (0.00s)
=== RUN   TestNotificationService_TemplateCRUD
=== PAUSE TestNotificationService_TemplateCRUD
=== RUN   TestNotificationService_Create
--- PASS: TestNotificationService_Create (0.00s)
=== RUN   TestNotificationService_List
--- PASS: TestNotificationService_List (0.00s)
=== RUN   TestNotificationService_MarkAsRead
--- PASS: TestNotificationService_MarkAsRead (0.00s)
=== RUN   TestNotificationService_MarkAllAsRead
--- PASS: TestNotificationService_MarkAllAsRead (0.00s)
=== RUN   TestNotificationService_Providers
--- PASS: TestNotificationService_Providers (0.00s)
=== RUN   TestNotificationService_TestProvider_Webhook
--- PASS: TestNotificationService_TestProvider_Webhook (0.00s)
=== RUN   TestNotificationService_SendExternal
--- PASS: TestNotificationService_SendExternal (0.00s)
=== RUN   TestNotificationService_SendExternal_MinimalVsDetailedTemplates
--- PASS: TestNotificationService_SendExternal_MinimalVsDetailedTemplates (0.00s)
=== RUN   TestNotificationService_SendExternal_Filtered
--- PASS: TestNotificationService_SendExternal_Filtered (0.10s)
=== RUN   TestNotificationService_SendExternal_Shoutrrr
--- PASS: TestNotificationService_SendExternal_Shoutrrr (0.10s)
=== RUN   TestNormalizeURL
=== RUN   TestNormalizeURL/Discord_HTTPS
=== RUN   TestNormalizeURL/Discord_HTTPS_with_app
=== RUN   TestNormalizeURL/Discord_Shoutrrr
=== RUN   TestNormalizeURL/Other_Service
--- PASS: TestNormalizeURL (0.00s)
    --- PASS: TestNormalizeURL/Discord_HTTPS (0.00s)
    --- PASS: TestNormalizeURL/Discord_HTTPS_with_app (0.00s)
    --- PASS: TestNormalizeURL/Discord_Shoutrrr (0.00s)
    --- PASS: TestNormalizeURL/Other_Service (0.00s)
=== RUN   TestNotificationService_SendCustomWebhook_Errors
=== RUN   TestNotificationService_SendCustomWebhook_Errors/invalid_URL
=== RUN   TestNotificationService_SendCustomWebhook_Errors/unreachable_host
=== RUN   TestNotificationService_SendCustomWebhook_Errors/server_returns_error
=== RUN   TestNotificationService_SendCustomWebhook_Errors/valid_custom_payload_template
=== RUN   TestNotificationService_SendCustomWebhook_Errors/default_payload_without_template
--- PASS: TestNotificationService_SendCustomWebhook_Errors (0.00s)
    --- PASS: TestNotificationService_SendCustomWebhook_Errors/invalid_URL (0.00s)
    --- PASS: TestNotificationService_SendCustomWebhook_Errors/unreachable_host (0.00s)
    --- PASS: TestNotificationService_SendCustomWebhook_Errors/server_returns_error (0.00s)
    --- PASS: TestNotificationService_SendCustomWebhook_Errors/valid_custom_payload_template (0.00s)
    --- PASS: TestNotificationService_SendCustomWebhook_Errors/default_payload_without_template (0.00s)
=== RUN   TestNotificationService_SendCustomWebhook_PropagatesRequestID
--- PASS: TestNotificationService_SendCustomWebhook_PropagatesRequestID (0.00s)
=== RUN   TestNotificationService_TestProvider_Errors
=== RUN   TestNotificationService_TestProvider_Errors/unsupported_provider_type
=== RUN   TestNotificationService_TestProvider_Errors/webhook_with_invalid_URL
=== RUN   TestNotificationService_TestProvider_Errors/discord_with_invalid_URL_format
=== RUN   TestNotificationService_TestProvider_Errors/slack_with_unreachable_webhook
=== RUN   TestNotificationService_TestProvider_Errors/webhook_success
--- PASS: TestNotificationService_TestProvider_Errors (0.00s)
    --- PASS: TestNotificationService_TestProvider_Errors/unsupported_provider_type (0.00s)
    --- PASS: TestNotificationService_TestProvider_Errors/webhook_with_invalid_URL (0.00s)
    --- PASS: TestNotificationService_TestProvider_Errors/discord_with_invalid_URL_format (0.00s)
    --- PASS: TestNotificationService_TestProvider_Errors/slack_with_unreachable_webhook (0.00s)
    --- PASS: TestNotificationService_TestProvider_Errors/webhook_success (0.00s)
=== RUN   TestValidateWebhookURL_PrivateIP
--- PASS: TestValidateWebhookURL_PrivateIP (0.00s)
=== RUN   TestNotificationService_SendExternal_EdgeCases
=== RUN   TestNotificationService_SendExternal_EdgeCases/no_enabled_providers
time="2025-12-12T19:01:47Z" level=error msg="Failed to send notification" error="failed to send discord notification: response status code 400 Bad Request" provider="Test Discord"
=== RUN   TestNotificationService_SendExternal_EdgeCases/provider_filtered_by_category
=== RUN   TestNotificationService_SendExternal_EdgeCases/custom_data_passed_to_webhook
--- PASS: TestNotificationService_SendExternal_EdgeCases (0.21s)
    --- PASS: TestNotificationService_SendExternal_EdgeCases/no_enabled_providers (0.05s)
    --- PASS: TestNotificationService_SendExternal_EdgeCases/provider_filtered_by_category (0.05s)
    --- PASS: TestNotificationService_SendExternal_EdgeCases/custom_data_passed_to_webhook (0.10s)
=== RUN   TestNotificationService_RenderTemplate
--- PASS: TestNotificationService_RenderTemplate (0.00s)
=== RUN   TestNotificationService_CreateProvider_Validation
=== RUN   TestNotificationService_CreateProvider_Validation/creates_provider_with_defaults
=== RUN   TestNotificationService_CreateProvider_Validation/updates_existing_provider
=== RUN   TestNotificationService_CreateProvider_Validation/deletes_non-existent_provider
--- PASS: TestNotificationService_CreateProvider_Validation (0.00s)
    --- PASS: TestNotificationService_CreateProvider_Validation/creates_provider_with_defaults (0.00s)
    --- PASS: TestNotificationService_CreateProvider_Validation/updates_existing_provider (0.00s)
    --- PASS: TestNotificationService_CreateProvider_Validation/deletes_non-existent_provider (0.00s)
=== RUN   TestNotificationService_IsPrivateIP
=== RUN   TestNotificationService_IsPrivateIP/loopback_ipv4
=== RUN   TestNotificationService_IsPrivateIP/loopback_ipv6
=== RUN   TestNotificationService_IsPrivateIP/private_10.x
=== RUN   TestNotificationService_IsPrivateIP/private_10.x_high
=== RUN   TestNotificationService_IsPrivateIP/private_172.16-31
=== RUN   TestNotificationService_IsPrivateIP/private_172.31
=== RUN   TestNotificationService_IsPrivateIP/private_192.168
=== RUN   TestNotificationService_IsPrivateIP/public_172.32
=== RUN   TestNotificationService_IsPrivateIP/public_172.15
=== RUN   TestNotificationService_IsPrivateIP/public_ip
=== RUN   TestNotificationService_IsPrivateIP/public_ipv6
=== RUN   TestNotificationService_IsPrivateIP/link_local_ipv4
=== RUN   TestNotificationService_IsPrivateIP/link_local_ipv6
=== RUN   TestNotificationService_IsPrivateIP/unique_local_ipv6_fc
=== RUN   TestNotificationService_IsPrivateIP/unique_local_ipv6_fc_high
=== RUN   TestNotificationService_IsPrivateIP/unique_local_ipv6_fd
--- PASS: TestNotificationService_IsPrivateIP (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/loopback_ipv4 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/loopback_ipv6 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/private_10.x (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/private_10.x_high (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/private_172.16-31 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/private_172.31 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/private_192.168 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/public_172.32 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/public_172.15 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/public_ip (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/public_ipv6 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/link_local_ipv4 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/link_local_ipv6 (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/unique_local_ipv6_fc (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/unique_local_ipv6_fc_high (0.00s)
    --- PASS: TestNotificationService_IsPrivateIP/unique_local_ipv6_fd (0.00s)
=== RUN   TestNotificationService_CreateProvider_InvalidCustomTemplate
=== RUN   TestNotificationService_CreateProvider_InvalidCustomTemplate/invalid_custom_template_on_create
=== RUN   TestNotificationService_CreateProvider_InvalidCustomTemplate/invalid_custom_template_on_update
--- PASS: TestNotificationService_CreateProvider_InvalidCustomTemplate (0.00s)
    --- PASS: TestNotificationService_CreateProvider_InvalidCustomTemplate/invalid_custom_template_on_create (0.00s)
    --- PASS: TestNotificationService_CreateProvider_InvalidCustomTemplate/invalid_custom_template_on_update (0.00s)
=== RUN   TestProxyHostService_ValidateUniqueDomain
=== RUN   TestProxyHostService_ValidateUniqueDomain/New_unique_domain
=== RUN   TestProxyHostService_ValidateUniqueDomain/Duplicate_domain
=== RUN   TestProxyHostService_ValidateUniqueDomain/Same_domain_but_excluded_ID_(update_self)
--- PASS: TestProxyHostService_ValidateUniqueDomain (0.00s)
    --- PASS: TestProxyHostService_ValidateUniqueDomain/New_unique_domain (0.00s)
    --- PASS: TestProxyHostService_ValidateUniqueDomain/Duplicate_domain (0.00s)
    --- PASS: TestProxyHostService_ValidateUniqueDomain/Same_domain_but_excluded_ID_(update_self) (0.00s)
=== RUN   TestProxyHostService_CRUD

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:103 [35;1mrecord not found
[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE `proxy_hosts`.`id` = 1 ORDER BY `proxy_hosts`.`id` LIMIT 1
--- PASS: TestProxyHostService_CRUD (0.00s)
=== RUN   TestProxyHostService_TestConnection
--- PASS: TestProxyHostService_TestConnection (0.00s)
=== RUN   TestProxyHostService_AdvancedConfig
=== RUN   TestProxyHostService_AdvancedConfig/Empty_advanced_config
=== RUN   TestProxyHostService_AdvancedConfig/Valid_JSON_object
=== RUN   TestProxyHostService_AdvancedConfig/Valid_JSON_array
=== RUN   TestProxyHostService_AdvancedConfig/Invalid_JSON
=== RUN   TestProxyHostService_AdvancedConfig/Valid_nested_config
--- PASS: TestProxyHostService_AdvancedConfig (0.00s)
    --- PASS: TestProxyHostService_AdvancedConfig/Empty_advanced_config (0.00s)
    --- PASS: TestProxyHostService_AdvancedConfig/Valid_JSON_object (0.00s)
    --- PASS: TestProxyHostService_AdvancedConfig/Valid_JSON_array (0.00s)
    --- PASS: TestProxyHostService_AdvancedConfig/Invalid_JSON (0.00s)
    --- PASS: TestProxyHostService_AdvancedConfig/Valid_nested_config (0.00s)
=== RUN   TestProxyHostService_UpdateAdvancedConfig
--- PASS: TestProxyHostService_UpdateAdvancedConfig (0.00s)
=== RUN   TestProxyHostService_EmptyDomain
--- PASS: TestProxyHostService_EmptyDomain (0.00s)
=== RUN   TestRemoteServerService_ValidateUniqueServer
--- PASS: TestRemoteServerService_ValidateUniqueServer (0.00s)
=== RUN   TestRemoteServerService_CRUD

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:68 [35;1mrecord not found
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE `remote_servers`.`id` = 2 ORDER BY `remote_servers`.`id` LIMIT 1
--- PASS: TestRemoteServerService_CRUD (0.00s)
=== RUN   TestNewSecurityNotificationService
--- PASS: TestNewSecurityNotificationService (0.00s)
=== RUN   TestSecurityNotificationService_GetSettings_Default

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1mrecord not found
[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationService_GetSettings_Default (0.00s)
=== RUN   TestSecurityNotificationService_UpdateSettings

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationService_UpdateSettings (0.00s)
=== RUN   TestSecurityNotificationService_UpdateSettings_Existing

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationService_UpdateSettings_Existing (0.00s)
=== RUN   TestSecurityNotificationService_Send_Disabled

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1mrecord not found
[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationService_Send_Disabled (0.00s)
=== RUN   TestSecurityNotificationService_Send_FilteredByEventType

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationService_Send_FilteredByEventType (0.00s)
=== RUN   TestSecurityNotificationService_Send_FilteredBySeverity

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationService_Send_FilteredBySeverity (0.00s)
=== RUN   TestSecurityNotificationService_Send_WebhookSuccess

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationService_Send_WebhookSuccess (0.00s)
=== RUN   TestSecurityNotificationService_Send_WebhookFailure

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.040ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
time="2025-12-12T19:01:47Z" level=error msg="Failed to send webhook notification" error="webhook returned status 500"
--- PASS: TestSecurityNotificationService_Send_WebhookFailure (0.00s)
=== RUN   TestShouldNotify
=== RUN   TestShouldNotify/error_>=_error
=== RUN   TestShouldNotify/warn_<_error
=== RUN   TestShouldNotify/error_>=_warn
=== RUN   TestShouldNotify/info_>=_info
=== RUN   TestShouldNotify/debug_<_info
=== RUN   TestShouldNotify/error_>=_debug
--- PASS: TestShouldNotify (0.00s)
    --- PASS: TestShouldNotify/error_>=_error (0.00s)
    --- PASS: TestShouldNotify/warn_<_error (0.00s)
    --- PASS: TestShouldNotify/error_>=_warn (0.00s)
    --- PASS: TestShouldNotify/info_>=_info (0.00s)
    --- PASS: TestShouldNotify/debug_<_info (0.00s)
    --- PASS: TestShouldNotify/error_>=_debug (0.00s)
=== RUN   TestSecurityNotificationService_Send_ACLDeny

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
--- PASS: TestSecurityNotificationService_Send_ACLDeny (0.00s)
=== RUN   TestSecurityNotificationService_Send_ContextTimeout

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
time="2025-12-12T19:01:47Z" level=error msg="Failed to send webhook notification" error="execute request: Post \"http://127.0.0.1:41425\": context deadline exceeded"
--- PASS: TestSecurityNotificationService_Send_ContextTimeout (0.10s)
=== RUN   TestSecurityService_Upsert_ValidateAdminWhitelist

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_Upsert_ValidateAdminWhitelist (0.00s)
=== RUN   TestSecurityService_BreakGlassTokenLifecycle

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_BreakGlassTokenLifecycle (0.18s)
=== RUN   TestSecurityService_LogDecisionAndList
--- PASS: TestSecurityService_LogDecisionAndList (0.00s)
=== RUN   TestSecurityService_UpsertRuleSet

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "owasp-crs" ORDER BY `security_rule_sets`.`id` LIMIT 1
--- PASS: TestSecurityService_UpsertRuleSet (0.00s)
=== RUN   TestSecurityService_UpsertRuleSet_ContentTooLarge
--- PASS: TestSecurityService_UpsertRuleSet_ContentTooLarge (0.01s)
=== RUN   TestSecurityService_DeleteRuleSet

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mrecord not found
[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "owasp-crs" ORDER BY `security_rule_sets`.`id` LIMIT 1
--- PASS: TestSecurityService_DeleteRuleSet (0.00s)
=== RUN   TestSecurityService_Upsert_RejectExternalMode

2025/12/12 19:01:47 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.048ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_Upsert_RejectExternalMode (0.00s)
=== RUN   TestSecurityService_GenerateBreakGlassToken_NewConfig

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:121 [35;1mrecord not found
[0m[33m[0.175ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "newconfig" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_GenerateBreakGlassToken_NewConfig (0.13s)
=== RUN   TestSecurityService_GenerateBreakGlassToken_UpdateExisting

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_GenerateBreakGlassToken_UpdateExisting (0.24s)
=== RUN   TestSecurityService_VerifyBreakGlassToken_NoConfig

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:142 [35;1mrecord not found
[0m[33m[0.048ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "nonexistent" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_VerifyBreakGlassToken_NoConfig (0.00s)
=== RUN   TestSecurityService_VerifyBreakGlassToken_NoHash

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.042ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_VerifyBreakGlassToken_NoHash (0.00s)
=== RUN   TestSecurityService_VerifyBreakGlassToken_WrongToken

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:121 [35;1mrecord not found
[0m[33m[0.161ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_VerifyBreakGlassToken_WrongToken (0.36s)
=== RUN   TestSecurityService_Get_NotFound

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
[0m[33m[0.035ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_Get_NotFound (0.00s)
=== RUN   TestSecurityService_Upsert_PreserveBreakGlassHash

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:121 [35;1mrecord not found
[0m[33m[0.141ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_Upsert_PreserveBreakGlassHash (0.12s)
=== RUN   TestSecurityService_Upsert_RateLimitFieldsPersist

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.035ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_Upsert_RateLimitFieldsPersist (0.00s)
=== RUN   TestSecurityService_LogAudit
--- PASS: TestSecurityService_LogAudit (0.00s)
=== RUN   TestSecurityService_DeleteRuleSet_NotFound

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:234 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE `security_rule_sets`.`id` = 9999 ORDER BY `security_rule_sets`.`id` LIMIT 1
--- PASS: TestSecurityService_DeleteRuleSet_NotFound (0.00s)
=== RUN   TestSecurityService_ListDecisions_UnlimitedAndLimited
--- PASS: TestSecurityService_ListDecisions_UnlimitedAndLimited (0.00s)
=== RUN   TestSecurityService_LogDecision_Nil
--- PASS: TestSecurityService_LogDecision_Nil (0.00s)
=== RUN   TestSecurityService_LogDecision_PrefilledUUID
--- PASS: TestSecurityService_LogDecision_PrefilledUUID (0.00s)
=== RUN   TestSecurityService_ListRuleSets_Empty
--- PASS: TestSecurityService_ListRuleSets_Empty (0.00s)
=== RUN   TestSecurityService_Upsert_InvalidCrowdSecMode

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
--- PASS: TestSecurityService_Upsert_InvalidCrowdSecMode (0.00s)
=== RUN   TestUpdateService_CheckForUpdates
--- PASS: TestUpdateService_CheckForUpdates (0.00s)
=== RUN   TestUptimeService_sendRecoveryNotification
=== PAUSE TestUptimeService_sendRecoveryNotification
=== RUN   TestUptimeService_CheckAll

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.061ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "127.0.0.1" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:48Z" level=info msg="Created UptimeHost" host=127.0.0.1 host_id=74fe6813-2845-487e-b7be-5115a6a04ade

2025/12/12 19:01:48 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.056ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 2 ORDER BY `uptime_monitors`.`id` LIMIT 1
time="2025-12-12T19:01:49Z" level=info msg="Host status changed" host_ip=127.0.0.1 host_name="127.0.0.1:34511" message="dial tcp 127.0.0.1:34097: connect: connection refused" new=down old=up
time="2025-12-12T19:01:49Z" level=info msg="Sent consolidated DOWN notification" host_name="127.0.0.1:34511" service_count=1
--- PASS: TestUptimeService_CheckAll (1.74s)
=== RUN   TestUptimeService_ListMonitors
--- PASS: TestUptimeService_ListMonitors (0.01s)
=== RUN   TestUptimeService_GetMonitorByID
=== RUN   TestUptimeService_GetMonitorByID/get_existing_monitor
=== RUN   TestUptimeService_GetMonitorByID/get_non-existent_monitor

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:869 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "non-existent" ORDER BY `uptime_monitors`.`id` LIMIT 1
--- PASS: TestUptimeService_GetMonitorByID (0.01s)
    --- PASS: TestUptimeService_GetMonitorByID/get_existing_monitor (0.00s)
    --- PASS: TestUptimeService_GetMonitorByID/get_non-existent_monitor (0.00s)
=== RUN   TestUptimeService_GetMonitorHistory
--- PASS: TestUptimeService_GetMonitorHistory (0.01s)
=== RUN   TestUptimeService_SyncMonitors_Errors
=== RUN   TestUptimeService_SyncMonitors_Errors/database_error_during_proxy_host_fetch

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:105 [35;1msql: database is closed
[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
=== RUN   TestUptimeService_SyncMonitors_Errors/creates_monitors_for_new_hosts

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.050ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host= host_id=26cd5331-60ed-4ee6-9de6-0d715d027535

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 2 ORDER BY `uptime_monitors`.`id` LIMIT 1
=== RUN   TestUptimeService_SyncMonitors_Errors/orphaned_monitors_persist_after_host_deletion

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host= host_id=c1b153d4-c37f-4d0f-9529-386f5687e14d
--- PASS: TestUptimeService_SyncMonitors_Errors (0.03s)
    --- PASS: TestUptimeService_SyncMonitors_Errors/database_error_during_proxy_host_fetch (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_Errors/creates_monitors_for_new_hosts (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_Errors/orphaned_monitors_persist_after_host_deletion (0.01s)
=== RUN   TestUptimeService_SyncMonitors_NameSync
=== RUN   TestUptimeService_SyncMonitors_NameSync/syncs_name_from_proxy_host_when_changed

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.054ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host= host_id=7564348b-8a58-497e-ac17-0a4ffa73c0da
=== RUN   TestUptimeService_SyncMonitors_NameSync/uses_domain_name_when_proxy_host_name_is_empty

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host= host_id=3c7ef273-e0b7-436b-bd6d-805a8faa99f3
=== RUN   TestUptimeService_SyncMonitors_NameSync/updates_monitor_name_when_host_name_becomes_empty

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.058ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host= host_id=4748c52b-b02f-4cf7-a0b2-a64c174f2b4a
--- PASS: TestUptimeService_SyncMonitors_NameSync (0.03s)
    --- PASS: TestUptimeService_SyncMonitors_NameSync/syncs_name_from_proxy_host_when_changed (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_NameSync/uses_domain_name_when_proxy_host_name_is_empty (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_NameSync/updates_monitor_name_when_host_name_becomes_empty (0.01s)
=== RUN   TestUptimeService_SyncMonitors_TCPMigration
=== RUN   TestUptimeService_SyncMonitors_TCPMigration/migrates_TCP_monitor_to_HTTP_for_public_URL

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "backend.local" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host=backend.local host_id=152ae32f-d0e3-49e2-8696-1a2bf56dd256
time="2025-12-12T19:01:50Z" level=info msg="Migrated monitor for host 1 to check public URL: http://public.com" host_id=1
=== RUN   TestUptimeService_SyncMonitors_TCPMigration/does_not_migrate_TCP_monitor_with_custom_URL

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "backend.local" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host=backend.local host_id=3b1e92b7-7a16-48dd-9dbb-554ce01f8826
--- PASS: TestUptimeService_SyncMonitors_TCPMigration (0.02s)
    --- PASS: TestUptimeService_SyncMonitors_TCPMigration/migrates_TCP_monitor_to_HTTP_for_public_URL (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_TCPMigration/does_not_migrate_TCP_monitor_with_custom_URL (0.01s)
=== RUN   TestUptimeService_SyncMonitors_HTTPSUpgrade
=== RUN   TestUptimeService_SyncMonitors_HTTPSUpgrade/upgrades_HTTP_to_HTTPS_when_SSL_forced

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host= host_id=17b65706-637c-4d22-9380-9908579c49d3
time="2025-12-12T19:01:50Z" level=info msg="Upgraded monitor for host 1 to HTTPS: https://secure.com" host_id=1
=== RUN   TestUptimeService_SyncMonitors_HTTPSUpgrade/does_not_downgrade_HTTPS_when_SSL_not_forced

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host= host_id=fef11b5c-cdc7-4e30-9fec-78189c6431f6
--- PASS: TestUptimeService_SyncMonitors_HTTPSUpgrade (0.02s)
    --- PASS: TestUptimeService_SyncMonitors_HTTPSUpgrade/upgrades_HTTP_to_HTTPS_when_SSL_forced (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_HTTPSUpgrade/does_not_downgrade_HTTPS_when_SSL_not_forced (0.01s)
=== RUN   TestUptimeService_SyncMonitors_RemoteServers
=== RUN   TestUptimeService_SyncMonitors_RemoteServers/creates_monitor_for_new_remote_server

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:210 [35;1mrecord not found
[0m[33m[0.059ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE remote_server_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.043ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "backend.local" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host=backend.local host_id=74908064-6ad0-4532-9711-93a7848947bc
=== RUN   TestUptimeService_SyncMonitors_RemoteServers/creates_TCP_monitor_for_remote_server_without_scheme

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:210 [35;1mrecord not found
[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE remote_server_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "tcp.backend" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host=tcp.backend host_id=593e3c1e-c6a8-4d4a-86e1-c197048a59b3
=== RUN   TestUptimeService_SyncMonitors_RemoteServers/syncs_remote_server_name_changes

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:210 [35;1mrecord not found
[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE remote_server_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "server.local" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host=server.local host_id=d1c46790-6ec2-4dee-a3d5-966fe241d615
=== RUN   TestUptimeService_SyncMonitors_RemoteServers/syncs_remote_server_URL_changes

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:210 [35;1mrecord not found
[0m[33m[0.105ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE remote_server_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "old.host" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host=old.host host_id=9b0ac32c-6646-4a47-ba74-7608e35ef25b
=== RUN   TestUptimeService_SyncMonitors_RemoteServers/syncs_remote_server_enabled_status

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:210 [35;1mrecord not found
[0m[33m[0.049ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE remote_server_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "server.local" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host=server.local host_id=9d5ab0eb-fd75-488b-af31-c45ca72b72cf
=== RUN   TestUptimeService_SyncMonitors_RemoteServers/syncs_scheme_change_from_TCP_to_HTTPS

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:210 [35;1mrecord not found
[0m[33m[0.042ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE remote_server_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "server.local" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host=server.local host_id=812922d2-8e38-4997-8df2-deb0220a535f
--- PASS: TestUptimeService_SyncMonitors_RemoteServers (0.07s)
    --- PASS: TestUptimeService_SyncMonitors_RemoteServers/creates_monitor_for_new_remote_server (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_RemoteServers/creates_TCP_monitor_for_remote_server_without_scheme (0.02s)
    --- PASS: TestUptimeService_SyncMonitors_RemoteServers/syncs_remote_server_name_changes (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_RemoteServers/syncs_remote_server_URL_changes (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_RemoteServers/syncs_remote_server_enabled_status (0.01s)
    --- PASS: TestUptimeService_SyncMonitors_RemoteServers/syncs_scheme_change_from_TCP_to_HTTPS (0.01s)
=== RUN   TestUptimeService_CheckAll_Errors
=== RUN   TestUptimeService_CheckAll_Errors/handles_empty_monitor_list
=== RUN   TestUptimeService_CheckAll_Errors/orphan_monitors_don't_prevent_check_execution
=== RUN   TestUptimeService_CheckAll_Errors/handles_timeout_for_slow_hosts

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.067ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:50 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.035ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "192.0.2.1" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:50Z" level=info msg="Created UptimeHost" host=192.0.2.1 host_id=b3a78269-2e94-4ebd-a939-260f1b342854
--- PASS: TestUptimeService_CheckAll_Errors (7.19s)
    --- PASS: TestUptimeService_CheckAll_Errors/handles_empty_monitor_list (0.06s)
    --- PASS: TestUptimeService_CheckAll_Errors/orphan_monitors_don't_prevent_check_execution (0.11s)
    --- PASS: TestUptimeService_CheckAll_Errors/handles_timeout_for_slow_hosts (7.02s)
=== RUN   TestUptimeService_CheckMonitor_EdgeCases
=== RUN   TestUptimeService_CheckMonitor_EdgeCases/invalid_URL_format
=== RUN   TestUptimeService_CheckMonitor_EdgeCases/http_404_response_treated_as_down

2025/12/12 19:01:58 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.059ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:01:58 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.074ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "127.0.0.1" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:01:58Z" level=info msg="Created UptimeHost" host=127.0.0.1 host_id=b1a034b5-115f-45cf-bd08-eecc88f5786e
=== RUN   TestUptimeService_CheckMonitor_EdgeCases/https_URL_without_valid_certificate
--- PASS: TestUptimeService_CheckMonitor_EdgeCases (3.89s)
    --- PASS: TestUptimeService_CheckMonitor_EdgeCases/invalid_URL_format (0.51s)
    --- PASS: TestUptimeService_CheckMonitor_EdgeCases/http_404_response_treated_as_down (0.37s)
    --- PASS: TestUptimeService_CheckMonitor_EdgeCases/https_URL_without_valid_certificate (3.01s)
=== RUN   TestUptimeService_GetMonitorHistory_EdgeCases
=== RUN   TestUptimeService_GetMonitorHistory_EdgeCases/non-existent_monitor
=== RUN   TestUptimeService_GetMonitorHistory_EdgeCases/limit_parameter_respected
--- PASS: TestUptimeService_GetMonitorHistory_EdgeCases (0.05s)
    --- PASS: TestUptimeService_GetMonitorHistory_EdgeCases/non-existent_monitor (0.02s)
    --- PASS: TestUptimeService_GetMonitorHistory_EdgeCases/limit_parameter_respected (0.02s)
=== RUN   TestUptimeService_ListMonitors_EdgeCases
=== RUN   TestUptimeService_ListMonitors_EdgeCases/empty_database
=== RUN   TestUptimeService_ListMonitors_EdgeCases/monitors_with_associated_proxy_hosts
--- PASS: TestUptimeService_ListMonitors_EdgeCases (0.04s)
    --- PASS: TestUptimeService_ListMonitors_EdgeCases/empty_database (0.02s)
    --- PASS: TestUptimeService_ListMonitors_EdgeCases/monitors_with_associated_proxy_hosts (0.02s)
=== RUN   TestUptimeService_UpdateMonitor
=== RUN   TestUptimeService_UpdateMonitor/update_max_retries
=== RUN   TestUptimeService_UpdateMonitor/update_interval
=== RUN   TestUptimeService_UpdateMonitor/update_non-existent_monitor

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:883 [35;1mrecord not found
[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "non-existent" ORDER BY `uptime_monitors`.`id` LIMIT 1
=== RUN   TestUptimeService_UpdateMonitor/update_multiple_fields
--- PASS: TestUptimeService_UpdateMonitor (0.10s)
    --- PASS: TestUptimeService_UpdateMonitor/update_max_retries (0.02s)
    --- PASS: TestUptimeService_UpdateMonitor/update_interval (0.03s)
    --- PASS: TestUptimeService_UpdateMonitor/update_non-existent_monitor (0.02s)
    --- PASS: TestUptimeService_UpdateMonitor/update_multiple_fields (0.03s)
=== RUN   TestUptimeService_NotificationBatching
=== RUN   TestUptimeService_NotificationBatching/batches_multiple_service_failures_on_same_host
time="2025-12-12T19:02:02Z" level=info msg="Created pending notification batch" host="Test Server" monitor="Service A"
time="2025-12-12T19:02:02Z" level=info msg="Added to pending notification batch" count=2 host="Test Server" monitor="Service B"
time="2025-12-12T19:02:02Z" level=info msg="Added to pending notification batch" count=3 host="Test Server" monitor="Service C"
time="2025-12-12T19:02:02Z" level=info msg="Sent batched DOWN notification" count=3 host="Test Server"
=== RUN   TestUptimeService_NotificationBatching/single_service_down_gets_individual_notification
time="2025-12-12T19:02:02Z" level=info msg="Created pending notification batch" host="Single Service Host" monitor="Lonely Service"
time="2025-12-12T19:02:02Z" level=info msg="Sent batched DOWN notification" count=1 host="Single Service Host"
--- PASS: TestUptimeService_NotificationBatching (0.07s)
    --- PASS: TestUptimeService_NotificationBatching/batches_multiple_service_failures_on_same_host (0.05s)
    --- PASS: TestUptimeService_NotificationBatching/single_service_down_gets_individual_notification (0.03s)
=== RUN   TestUptimeService_HostLevelCheck
=== RUN   TestUptimeService_HostLevelCheck/creates_uptime_host_during_sync

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.057ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "10.0.0.50" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:02:02Z" level=info msg="Created UptimeHost" host=10.0.0.50 host_id=c0ba9030-593f-4b3d-8af1-628f6aa9bc10
=== RUN   TestUptimeService_HostLevelCheck/groups_multiple_services_on_same_host

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "10.0.0.100" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:02:02Z" level=info msg="Created UptimeHost" host=10.0.0.100 host_id=8d650e75-5645-4b65-8384-741dae225532

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.049ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 2 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 3 ORDER BY `uptime_monitors`.`id` LIMIT 1
--- PASS: TestUptimeService_HostLevelCheck (0.07s)
    --- PASS: TestUptimeService_HostLevelCheck/creates_uptime_host_during_sync (0.04s)
    --- PASS: TestUptimeService_HostLevelCheck/groups_multiple_services_on_same_host (0.03s)
=== RUN   TestFormatDuration
--- PASS: TestFormatDuration (0.00s)
=== RUN   TestUptimeService_SyncMonitorForHost
=== RUN   TestUptimeService_SyncMonitorForHost/updates_monitor_when_proxy_host_is_edited

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.046ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "10.0.0.1" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:02:02Z" level=info msg="Created UptimeHost" host=10.0.0.1 host_id=5d4ca013-a842-4931-a222-4c3100bcac14
=== RUN   TestUptimeService_SyncMonitorForHost/returns_nil_when_no_monitor_exists

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:828 [35;1mrecord not found
[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1
=== RUN   TestUptimeService_SyncMonitorForHost/returns_error_when_host_does_not_exist

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:823 [35;1mrecord not found
[0m[33m[0.049ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE `proxy_hosts`.`id` = 99999 ORDER BY `proxy_hosts`.`id` LIMIT 1
=== RUN   TestUptimeService_SyncMonitorForHost/uses_domain_name_when_proxy_host_name_is_empty

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.065ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "10.0.0.4" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:02:02Z" level=info msg="Created UptimeHost" host=10.0.0.4 host_id=a4fdc308-4a6f-49d5-8594-cd0d876ce24a
=== RUN   TestUptimeService_SyncMonitorForHost/handles_multiple_domains_correctly

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
[0m[33m[0.085ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
[0m[33m[0.056ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "10.0.0.5" ORDER BY `uptime_hosts`.`id` LIMIT 1
time="2025-12-12T19:02:02Z" level=info msg="Created UptimeHost" host=10.0.0.5 host_id=d8947473-5cde-4eff-8bc0-307e1f41065a
--- PASS: TestUptimeService_SyncMonitorForHost (0.09s)
    --- PASS: TestUptimeService_SyncMonitorForHost/updates_monitor_when_proxy_host_is_edited (0.02s)
    --- PASS: TestUptimeService_SyncMonitorForHost/returns_nil_when_no_monitor_exists (0.02s)
    --- PASS: TestUptimeService_SyncMonitorForHost/returns_error_when_host_does_not_exist (0.02s)
    --- PASS: TestUptimeService_SyncMonitorForHost/uses_domain_name_when_proxy_host_name_is_empty (0.02s)
    --- PASS: TestUptimeService_SyncMonitorForHost/handles_multiple_domains_correctly (0.02s)
=== RUN   TestExtractPort
=== RUN   TestExtractPort/http_url_default
=== RUN   TestExtractPort/https_url_default
=== RUN   TestExtractPort/http_with_port
=== RUN   TestExtractPort/https_with_port
=== RUN   TestExtractPort/host:port
=== RUN   TestExtractPort/plain_host
=== RUN   TestExtractPort/localhost_with_port
=== RUN   TestExtractPort/ip_with_port
=== RUN   TestExtractPort/ipv6_with_port
--- PASS: TestExtractPort (0.00s)
    --- PASS: TestExtractPort/http_url_default (0.00s)
    --- PASS: TestExtractPort/https_url_default (0.00s)
    --- PASS: TestExtractPort/http_with_port (0.00s)
    --- PASS: TestExtractPort/https_with_port (0.00s)
    --- PASS: TestExtractPort/host:port (0.00s)
    --- PASS: TestExtractPort/plain_host (0.00s)
    --- PASS: TestExtractPort/localhost_with_port (0.00s)
    --- PASS: TestExtractPort/ip_with_port (0.00s)
    --- PASS: TestExtractPort/ipv6_with_port (0.00s)
=== RUN   TestUpdateMonitorEnabled_Unit
--- PASS: TestUpdateMonitorEnabled_Unit (0.00s)
=== RUN   TestDeleteMonitorDeletesHeartbeats_Unit

2025/12/12 19:02:02 [31;1m/projects/Charon/backend/internal/services/uptime_service_unit_test.go:77 [35;1mrecord not found
[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "886f58b0-813d-4754-b0d5-e98b33b00415" ORDER BY `uptime_monitors`.`id` LIMIT 1
--- PASS: TestDeleteMonitorDeletesHeartbeats_Unit (0.00s)
=== RUN   TestCheckMonitor_PublicAPI
--- PASS: TestCheckMonitor_PublicAPI (7.87s)
=== RUN   TestCheckMonitor_InvalidURL
--- PASS: TestCheckMonitor_InvalidURL (0.00s)
=== RUN   TestCheckMonitor_TCPSuccess
--- PASS: TestCheckMonitor_TCPSuccess (0.01s)
=== RUN   TestCheckMonitor_TCPFailure
--- PASS: TestCheckMonitor_TCPFailure (10.00s)
=== RUN   TestCheckMonitor_UnknownType
--- PASS: TestCheckMonitor_UnknownType (0.00s)
=== RUN   TestDeleteMonitor_NonExistent

2025/12/12 19:02:20 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:911 [35;1mrecord not found
[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "non-existent-id" ORDER BY `uptime_monitors`.`id` LIMIT 1
--- PASS: TestDeleteMonitor_NonExistent (0.00s)
=== RUN   TestUpdateMonitor_NonExistent

2025/12/12 19:02:20 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:883 [35;1mrecord not found
[0m[33m[0.761ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "non-existent-id" ORDER BY `uptime_monitors`.`id` LIMIT 1
--- PASS: TestUpdateMonitor_NonExistent (0.00s)
=== CONT  TestBackupService_GetAvailableSpace
=== CONT  TestUptimeService_sendRecoveryNotification
=== RUN   TestBackupService_GetAvailableSpace/returns_space_for_existing_directory
=== PAUSE TestBackupService_GetAvailableSpace/returns_space_for_existing_directory
=== RUN   TestBackupService_GetAvailableSpace/errors_for_missing_directory
=== PAUSE TestBackupService_GetAvailableSpace/errors_for_missing_directory
=== CONT  TestBackupService_GetAvailableSpace/returns_space_for_existing_directory
=== CONT  TestNotificationService_TemplateCRUD
=== CONT  TestBackupService_GetAvailableSpace/errors_for_missing_directory
--- PASS: TestBackupService_GetAvailableSpace (0.00s)
    --- PASS: TestBackupService_GetAvailableSpace/returns_space_for_existing_directory (0.00s)
    --- PASS: TestBackupService_GetAvailableSpace/errors_for_missing_directory (0.00s)
--- PASS: TestUptimeService_sendRecoveryNotification (0.00s)
--- PASS: TestNotificationService_TemplateCRUD (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/services	(cached)
?   	github.com/Wikid82/charon/backend/internal/trace	[no test files]
=== RUN   TestSanitizeForLog
=== RUN   TestSanitizeForLog/empty_string
=== RUN   TestSanitizeForLog/clean_string
=== RUN   TestSanitizeForLog/string_with_newline
=== RUN   TestSanitizeForLog/string_with_carriage_return_and_newline
=== RUN   TestSanitizeForLog/string_with_multiple_newlines
=== RUN   TestSanitizeForLog/string_with_control_characters
=== RUN   TestSanitizeForLog/string_with_DEL_character_(0x7F)
=== RUN   TestSanitizeForLog/complex_string_with_mixed_control_chars
=== RUN   TestSanitizeForLog/string_with_tabs_(0x09_is_control_char)
=== RUN   TestSanitizeForLog/string_with_only_control_chars
--- PASS: TestSanitizeForLog (0.00s)
    --- PASS: TestSanitizeForLog/empty_string (0.00s)
    --- PASS: TestSanitizeForLog/clean_string (0.00s)
    --- PASS: TestSanitizeForLog/string_with_newline (0.00s)
    --- PASS: TestSanitizeForLog/string_with_carriage_return_and_newline (0.00s)
    --- PASS: TestSanitizeForLog/string_with_multiple_newlines (0.00s)
    --- PASS: TestSanitizeForLog/string_with_control_characters (0.00s)
    --- PASS: TestSanitizeForLog/string_with_DEL_character_(0x7F) (0.00s)
    --- PASS: TestSanitizeForLog/complex_string_with_mixed_control_chars (0.00s)
    --- PASS: TestSanitizeForLog/string_with_tabs_(0x09_is_control_char) (0.00s)
    --- PASS: TestSanitizeForLog/string_with_only_control_chars (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/util	(cached)
=== RUN   TestFull
--- PASS: TestFull (0.00s)
PASS
ok  	github.com/Wikid82/charon/backend/internal/version	(cached)
FAIL
