Files
3x-ui/internal/web/service/xray_restart_test.go
T
MHSanaei 40da7fdb76 fix(xray): retry a failed pending-restart instead of dropping the config change
The 30s cron consumed the need-restart flag with IsNeedRestartAndSetFalse before
calling RestartXray and only logged a failure. If RestartXray failed early (a
transient GetXrayConfig DB error) the old process kept running the old config,
the crash detector saw a running process and never retried, and the flag stayed
cleared — so an admin's saved change silently never reached the core. Move the
consume/restart/retry into ApplyPendingRestart, which re-arms the flag on
failure so the next tick retries.
2026-07-15 03:27:40 +02:00

47 lines
1.5 KiB
Go

package service
import (
"testing"
)
// A background (non-forced) restart — the pending-config-change cron, warp/ldap/
// outbound reconcile jobs — must not revive an Xray the admin deliberately
// stopped. Only an explicit forced restart clears the manual-stop state.
func TestRestartXrayRespectsManualStop(t *testing.T) {
setupSettingTestDB(t)
if err := (&SettingService{}).saveSetting("xrayTemplateConfig", "{ not valid json"); err != nil {
t.Fatalf("seed template: %v", err)
}
t.Cleanup(func() { isManuallyStopped.Store(false) })
isManuallyStopped.Store(true)
_ = (&XrayService{}).RestartXray(false)
if !isManuallyStopped.Load() {
t.Fatal("a non-forced restart cleared a deliberate manual stop and would revive xray")
}
}
// When the pending-restart reconcile consumes the need-restart flag but the
// restart itself fails, the flag must be re-armed so the config change is
// retried rather than silently dropped.
func TestApplyPendingRestartReArmsFlagOnFailure(t *testing.T) {
setupSettingTestDB(t)
if err := (&SettingService{}).saveSetting("xrayTemplateConfig", "{ not valid json"); err != nil {
t.Fatalf("seed template: %v", err)
}
t.Cleanup(func() {
isManuallyStopped.Store(false)
isNeedXrayRestart.Store(false)
})
isManuallyStopped.Store(false)
svc := &XrayService{}
svc.SetToNeedRestart()
svc.ApplyPendingRestart()
if !isNeedXrayRestart.Load() {
t.Fatal("a failed restart must re-arm the need-restart flag so the pending config change is retried")
}
}