Files
3x-ui/internal/web/web_shutdown_test.go
T
Rouzbeh† ad470681ef fix(web): stop clean shutdowns logging false errors, and let the panel stop its children (#6884)
A systemd stop or restart logged "Server shutdown failed: use of closed
network connection | xray is not running" on every clean exit. httpServer.Shutdown
already closes the listener, so the second Close's net.ErrClosed is now ignored,
and StopXray's not-running case is a sentinel (ErrXrayNotRunning) that Stop
treats as done.

The shipped units now use KillMode=mixed, so SIGTERM reaches only the panel,
which stops Xray and the sidecars itself; systemd still SIGKILLs whatever is left
after the stop timeout.
2026-10-24 05:15:34 +02:00

39 lines
953 B
Go

package web
import (
"context"
"net"
"net/http"
"testing"
"time"
)
func TestServerStopWhenXrayNotRunningSucceeds(t *testing.T) {
t.Setenv("XUI_DB_FOLDER", t.TempDir())
s := NewServer()
if err := s.Stop(); err != nil {
t.Fatalf("expected nil error when stopping server with unstarted xray, got: %v", err)
}
}
func TestServerStopPanelOnlyWithPreclosedListenerSucceeds(t *testing.T) {
t.Setenv("XUI_DB_FOLDER", t.TempDir())
s := NewServer()
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("net.Listen failed: %v", err)
}
s.listener = ln
s.httpServer = &http.Server{}
go func() { _ = s.httpServer.Serve(ln) }()
time.Sleep(10 * time.Millisecond)
shutdownCtx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
_ = s.httpServer.Shutdown(shutdownCtx)
if err := s.StopPanelOnly(); err != nil {
t.Fatalf("expected nil error when listener is already closed, got: %v", err)
}
}