Files
3x-ui-web-src/internal/web/job/xray_traffic_inform_test.go
Sanaei f727d04f65
CI / go-test (push) Canceled after 0s
CI / postgres-durable-first (push) Canceled after 0s
CI / codegen (push) Canceled after 0s
CI / govulncheck (push) Canceled after 0s
CI / race (push) Canceled after 0s
CI / fuzz-smoke (push) Canceled after 0s
CI / golangci (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CodeQL Advanced / Analyze (go) (push) Canceled after 0s
CodeQL Advanced / Analyze (actions) (push) Canceled after 0s
CodeQL Advanced / Analyze (javascript-typescript) (push) Canceled after 0s
Docs CI / build (push) Canceled after 0s
Docs Deploy (GitHub Pages) / build (push) Canceled after 0s
Release 3X-UI / build (386) (push) Canceled after 0s
Release 3X-UI / build (amd64) (push) Canceled after 0s
Release 3X-UI / build (arm64) (push) Canceled after 0s
Release 3X-UI / build (armv5) (push) Canceled after 0s
Release 3X-UI / build (armv6) (push) Canceled after 0s
Release 3X-UI / build (armv7) (push) Canceled after 0s
Release 3X-UI / build (s390x) (push) Canceled after 0s
Release 3X-UI / Build for Windows (amd64) (push) Canceled after 0s
Deploy Smoke Tests / noninteractive-install (ubuntu-24.04-arm) (push) Canceled after 0s
Deploy Smoke Tests / noninteractive-install (ubuntu-latest) (push) Canceled after 0s
Deploy Smoke Tests / release-tag-install (ubuntu-24.04-arm) (push) Canceled after 0s
Deploy Smoke Tests / release-tag-install (ubuntu-latest) (push) Canceled after 0s
Docs Deploy (GitHub Pages) / deploy (push) Canceled after 0s
Release 3X-UI / Publish rolling dev release (push) Canceled after 0s
v3.7.0
2026-08-24 15:07:15 +02:00

92 lines
2.3 KiB
Go

package job
import (
"errors"
"io"
"net"
"testing"
"time"
"github.com/valyala/fasthttp"
)
func stallingListener(t *testing.T) (addr string, release func()) {
t.Helper()
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("listen: %v", err)
}
done := make(chan struct{})
go func() {
defer close(done)
for {
conn, err := ln.Accept()
if err != nil {
return
}
go func(c net.Conn) {
<-done
_ = c.Close()
}(conn)
go func(c net.Conn) { _, _ = io.Copy(io.Discard, c) }(conn)
}
}()
return ln.Addr().String(), func() {
_ = ln.Close()
<-done
}
}
func TestExternalInformClient_StalledReceiverTimesOut(t *testing.T) {
addr, release := stallingListener(t)
defer release()
request := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(request)
request.Header.SetMethod("POST")
request.Header.SetContentType("application/json; charset=UTF-8")
request.SetBody([]byte(`{"clientTraffics":[],"inboundTraffics":[]}`))
request.SetRequestURI("http://" + addr + "/inform")
request.Header.SetConnectionClose()
response := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(response)
start := time.Now()
err := externalInformClient.DoTimeout(request, response, externalInformTimeout)
elapsed := time.Since(start)
if err == nil {
t.Fatal("a receiver that never answers must produce an error, not a completed request")
}
if !errors.Is(err, fasthttp.ErrTimeout) {
t.Errorf("want a timeout error, got %v", err)
}
if elapsed > externalInformTimeout+2*time.Second {
t.Errorf("call took %v, must be bounded by %v", elapsed, externalInformTimeout)
}
}
func TestExternalInformClient_HasDeadlines(t *testing.T) {
if externalInformClient.ReadTimeout <= 0 || externalInformClient.WriteTimeout <= 0 {
t.Fatal("the traffic-notify client must carry read and write deadlines")
}
if externalInformTimeout >= 5*time.Second {
t.Errorf("the call budget (%v) must stay under the 5s traffic poll cadence", externalInformTimeout)
}
}
func TestInformSkippedWhenNothingToReport(t *testing.T) {
j := &XrayTrafficJob{}
done := make(chan struct{})
go func() {
defer close(done)
j.informTrafficToExternalAPI(nil, nil)
}()
select {
case <-done:
case <-time.After(2 * time.Second):
t.Fatal("an empty payload must return before touching settings or the network")
}
}