98 lines
4.0 KiB
Go
98 lines
4.0 KiB
Go
package upstreamimpl
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
)
|
|
|
|
func TestGatewayTimeoutAllowsDelayedHeaders(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
time.Sleep(40 * time.Millisecond)
|
|
_, _ = w.Write([]byte(`{"code":0,"data":[]}`))
|
|
}))
|
|
defer server.Close()
|
|
client := g.Client()
|
|
other := g.Client()
|
|
original := other.Transport.(*http.Transport)
|
|
original.ResponseHeaderTimeout = time.Millisecond
|
|
client.Transport.(*http.Transport).ResponseHeaderTimeout = time.Millisecond
|
|
configureGatewayTimeout(context.Background(), client, "/sim/change/sim-apn", 1, time.Second)
|
|
response, err := client.Post(context.Background(), server.URL, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer response.Close()
|
|
if original.ResponseHeaderTimeout != time.Millisecond {
|
|
t.Fatal("修改了共享Transport")
|
|
}
|
|
}
|
|
|
|
func TestNonAPNGatewayTimeoutPreservesHeaderBudget(t *testing.T) {
|
|
client := g.Client()
|
|
transport := client.Transport.(*http.Transport)
|
|
transport.ResponseHeaderTimeout = 17 * time.Second
|
|
configureGatewayTimeout(context.Background(), client, "/sim/query/test", 2, 3*time.Second)
|
|
if client.Client.Timeout != 6*time.Second || transport.ResponseHeaderTimeout != 6*time.Second {
|
|
t.Fatalf("非APN响应头预算必须与请求预算一致:request=%s header=%s", client.Client.Timeout, transport.ResponseHeaderTimeout)
|
|
}
|
|
}
|
|
|
|
// TestNonAPNBatchExpandsHeaderBudget 覆盖批量停复机等非 APN 路径:
|
|
// 50 张卡按单卡预算放大后,响应头等待不能继续停留在 gclient 的 30 秒默认值。
|
|
func TestNonAPNBatchExpandsHeaderBudget(t *testing.T) {
|
|
client := g.Client()
|
|
transport := client.Transport.(*http.Transport)
|
|
transport.ResponseHeaderTimeout = 30 * time.Second
|
|
applyGatewayTimeout(client, "/sim/change/sim-status", 50, 10*time.Second, defaultDataServiceTimeout, defaultGatewayBatchTimeout)
|
|
if client.Client.Timeout != 500*time.Second {
|
|
t.Fatalf("请求预算=%s,期望500s", client.Client.Timeout)
|
|
}
|
|
if transport.ResponseHeaderTimeout != client.Client.Timeout {
|
|
t.Fatalf("响应头预算=%s与请求预算不一致", transport.ResponseHeaderTimeout)
|
|
}
|
|
}
|
|
|
|
// TestNonAPNBatchRespectsBatchTimeoutCap 保证异常上游不会无限占用连接:
|
|
// 超出批量上限时按上限截断,且响应头预算同步截断。
|
|
func TestNonAPNBatchRespectsBatchTimeoutCap(t *testing.T) {
|
|
client := g.Client()
|
|
transport := client.Transport.(*http.Transport)
|
|
applyGatewayTimeout(client, "/sim/query/usage", 1000, 10*time.Second, defaultDataServiceTimeout, defaultGatewayBatchTimeout)
|
|
if client.Client.Timeout != defaultGatewayBatchTimeout {
|
|
t.Fatalf("请求预算=%s,期望批量上限%s", client.Client.Timeout, defaultGatewayBatchTimeout)
|
|
}
|
|
if transport.ResponseHeaderTimeout != defaultGatewayBatchTimeout {
|
|
t.Fatalf("响应头预算=%s,期望批量上限%s", transport.ResponseHeaderTimeout, defaultGatewayBatchTimeout)
|
|
}
|
|
}
|
|
|
|
// TestNonAPNSingleCardKeepsPerCardBudget 保证单卡请求不被放大成批量预算。
|
|
func TestNonAPNSingleCardKeepsPerCardBudget(t *testing.T) {
|
|
for _, count := range []int{0, 1} {
|
|
client := g.Client()
|
|
transport := client.Transport.(*http.Transport)
|
|
applyGatewayTimeout(client, "/sim/query/test", count, 10*time.Second, defaultDataServiceTimeout, defaultGatewayBatchTimeout)
|
|
if client.Client.Timeout != 10*time.Second || transport.ResponseHeaderTimeout != 10*time.Second {
|
|
t.Fatalf("count=%d request=%s header=%s", count, client.Client.Timeout, transport.ResponseHeaderTimeout)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDataServiceTimeoutOverridesCardBudget(t *testing.T) {
|
|
for _, count := range []int{0, 1, 100} {
|
|
client := g.Client()
|
|
configureGatewayTimeout(context.Background(), client, "/sim/change/sim-apn", count, time.Millisecond)
|
|
if client.Client.Timeout != 210*time.Second {
|
|
t.Fatalf("count=%d timeout=%s", count, client.Client.Timeout)
|
|
}
|
|
if client.Transport.(*http.Transport).ResponseHeaderTimeout != client.Client.Timeout {
|
|
t.Fatal("响应头预算不一致")
|
|
}
|
|
}
|
|
}
|