test: verify native connection capacity recovery

This commit is contained in:
2026-09-21 03:17:17 +08:00
parent 241a568c83
commit efd3163902
3 changed files with 70 additions and 0 deletions

View File

@@ -444,6 +444,74 @@ func TestServerConcurrentRequestLimit(t *testing.T) {
}
}
func TestServerConnectionLimitReleasesAfterRequest(t *testing.T) {
started := make(chan struct{})
release := make(chan struct{})
application := omni.NewWithRouter(netrouter.New())
application.GET("/hold", func(ctx *omni.Context) error {
close(started)
<-release
return ctx.OK("done")
})
application.GET("/health", func(ctx *omni.Context) error { return ctx.OK("ok") })
server := native.New(application)
server.MaxConnections = 1
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
done := make(chan error, 1)
go func() { done <- server.Serve(context.Background(), listener) }()
waitForServer(t, listener.Addr().String())
defer stopServer(t, server, listener, done)
first, err := net.Dial("tcp", listener.Addr().String())
if err != nil {
t.Fatal(err)
}
defer first.Close()
_, _ = io.WriteString(first, "GET /hold HTTP/1.1\r\nHost: test\r\nConnection: close\r\n\r\n")
select {
case <-started:
case <-time.After(time.Second):
t.Fatal("first request did not start")
}
second, err := net.Dial("tcp", listener.Addr().String())
if err != nil {
t.Fatal(err)
}
second.SetReadDeadline(time.Now().Add(time.Second))
_, _ = io.WriteString(second, "GET /health HTTP/1.1\r\nHost: test\r\nConnection: close\r\n\r\n")
if _, err := second.Read(make([]byte, 1)); err == nil {
second.Close()
t.Fatal("connection over MaxConnections was not rejected")
}
second.Close()
close(release)
firstResponse, err := http.ReadResponse(bufio.NewReader(first), &http.Request{Method: http.MethodGet})
if err != nil {
t.Fatal(err)
}
firstResponse.Body.Close()
third, err := net.Dial("tcp", listener.Addr().String())
if err != nil {
t.Fatal(err)
}
defer third.Close()
_, _ = io.WriteString(third, "GET /health HTTP/1.1\r\nHost: test\r\nConnection: close\r\n\r\n")
thirdResponse, err := http.ReadResponse(bufio.NewReader(third), &http.Request{Method: http.MethodGet})
if err != nil {
t.Fatal(err)
}
thirdResponse.Body.Close()
if thirdResponse.StatusCode != http.StatusOK {
t.Fatalf("connection slot was not released, got status %d", thirdResponse.StatusCode)
}
}
func TestServerReadHeaderTimeout(t *testing.T) {
application := omni.NewWithRouter(netrouter.New())
application.GET("/health", func(ctx *omni.Context) error { return ctx.OK("ok") })