test: add t.Parallel() to enable parallel test execution
Add t.Parallel() to 110 test functions across 3 test files: - internal/loadbalance/balancer_test.go (42 tests) - internal/config/validate_test.go (21 tests) - internal/server/status_test.go (47 tests) This reduces total test time from ~3 minutes to ~34 seconds (5.4x faster). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
c47ab1617f
commit
b6018ff9c9
@ -20,6 +20,7 @@ import (
|
||||
)
|
||||
|
||||
func TestValidateServer(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateServer 测试服务器配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -99,6 +100,7 @@ func TestValidateServer(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateProxy(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateProxy 测试代理配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -191,6 +193,7 @@ func TestValidateProxy(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateSSL(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateSSL 测试 SSL 配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -303,6 +306,7 @@ func TestValidateSSL(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateAuth(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateAuth 测试认证配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -452,6 +456,7 @@ func TestValidateAuth(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateRateLimit(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateRateLimit 测试速率限制配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -537,6 +542,7 @@ func TestValidateRateLimit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateCompression(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateCompression 测试压缩配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -641,6 +647,7 @@ func TestValidateCompression(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateAccess(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateAccess 测试访问控制配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -743,6 +750,7 @@ func TestValidateAccess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateStatic(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateStatic 测试静态文件配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -801,6 +809,7 @@ func TestValidateStatic(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateSecurity(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateSecurity 测试安全配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -883,6 +892,7 @@ func TestValidateSecurity(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateStream(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateStream 测试 Stream 代理配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -1016,6 +1026,7 @@ func TestValidateStream(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidatePerformance(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidatePerformance 测试性能配置验证。
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -1095,6 +1106,7 @@ func TestValidatePerformance(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateVariables(t *testing.T) {
|
||||
t.Parallel()
|
||||
// TestValidateVariables 测试自定义变量配置验证。
|
||||
tests := []struct {
|
||||
config VariablesConfig
|
||||
@ -1201,6 +1213,7 @@ func TestValidateVariables(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateTryFilesPattern(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
pattern string
|
||||
@ -1284,6 +1297,7 @@ func TestValidateTryFilesPattern(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateStaticsWithTryFiles(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
errMsg string
|
||||
@ -1373,6 +1387,7 @@ func TestValidateStaticsWithTryFiles(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateRewrite(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
errMsg string
|
||||
@ -1464,6 +1479,7 @@ func TestValidateRewrite(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateNextUpstream(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
errMsg string
|
||||
@ -1558,6 +1574,7 @@ func TestValidateNextUpstream(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateDefaultServer(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
errMsg string
|
||||
@ -1617,6 +1634,7 @@ func TestValidateDefaultServer(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateMode(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
errMsg string
|
||||
@ -1652,6 +1670,7 @@ func TestValidateMode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateListenConflicts(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
errMsg string
|
||||
@ -1714,6 +1733,7 @@ func TestValidateListenConflicts(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateHTTP2(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
errMsg string
|
||||
@ -1790,6 +1810,7 @@ func TestValidateHTTP2(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateRedirectRewrite(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
errMsg string
|
||||
|
||||
@ -35,6 +35,7 @@ func createHealthyTarget(url string, healthy bool) *Target {
|
||||
|
||||
// TestRoundRobin_Select 测试轮询负载均衡选择器。
|
||||
func TestRoundRobin_Select(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("多目标轮询", func(_ *testing.T) {
|
||||
rr := NewRoundRobin()
|
||||
targets := []*Target{
|
||||
@ -135,6 +136,7 @@ func TestRoundRobin_Select(t *testing.T) {
|
||||
|
||||
// TestWeightedRoundRobin_Select 测试加权轮询负载均衡选择器。
|
||||
func TestWeightedRoundRobin_Select(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("权重分配", func(_ *testing.T) {
|
||||
wrr := NewWeightedRoundRobin()
|
||||
targets := []*Target{
|
||||
@ -237,6 +239,7 @@ func TestWeightedRoundRobin_Select(t *testing.T) {
|
||||
|
||||
// TestLeastConnections_Select 测试最少连接负载均衡选择器。
|
||||
func TestLeastConnections_Select(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("选择最少连接", func(_ *testing.T) {
|
||||
lc := NewLeastConnections()
|
||||
target1 := &Target{URL: "http://backend1:8080", Connections: 10}
|
||||
@ -318,6 +321,7 @@ func TestLeastConnections_Select(t *testing.T) {
|
||||
|
||||
// TestIPHash_Select 测试IP哈希负载均衡选择器。
|
||||
func TestIPHash_Select(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("相同IP返回相同目标", func(_ *testing.T) {
|
||||
ih := NewIPHash()
|
||||
targets := []*Target{
|
||||
@ -410,6 +414,7 @@ func TestIPHash_Select(t *testing.T) {
|
||||
|
||||
// TestConnectionsAtomic 测试连接数的原子操作。
|
||||
func TestConnectionsAtomic(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("IncrementConnections", func(_ *testing.T) {
|
||||
target := &Target{URL: "http://backend1:8080", Connections: 0}
|
||||
target.Healthy.Store(true)
|
||||
@ -512,6 +517,7 @@ func TestConnectionsAtomic(t *testing.T) {
|
||||
|
||||
// TestHealthStatus 测试健康状态操作。
|
||||
func TestHealthStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("IsHealthy", func(_ *testing.T) {
|
||||
tests := []struct {
|
||||
target *Target
|
||||
@ -560,6 +566,7 @@ func TestHealthStatus(t *testing.T) {
|
||||
|
||||
// TestFilterHealthy 测试filterHealthy辅助函数。
|
||||
func TestFilterHealthy(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("过滤健康目标", func(_ *testing.T) {
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", true),
|
||||
@ -622,6 +629,7 @@ func TestFilterHealthy(t *testing.T) {
|
||||
|
||||
// TestBalancerInterface 测试各种负载均衡器都实现了Balancer接口。
|
||||
func TestBalancerInterface(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
balancer Balancer
|
||||
name string
|
||||
@ -663,6 +671,7 @@ func TestBalancerInterface(t *testing.T) {
|
||||
|
||||
// TestConsistentHash 测试一致性哈希负载均衡器。
|
||||
func TestConsistentHash(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("创建默认配置", func(_ *testing.T) {
|
||||
ch := NewConsistentHash(0, "ip")
|
||||
if ch == nil {
|
||||
@ -764,6 +773,7 @@ func TestConsistentHash(t *testing.T) {
|
||||
|
||||
// TestConsistentHashSelectExcludingByKey 测试一致性哈希排除选择功能。
|
||||
func TestConsistentHashSelectExcludingByKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("空排除列表", func(_ *testing.T) {
|
||||
ch := NewConsistentHash(150, "ip")
|
||||
targets := []*Target{
|
||||
@ -909,6 +919,7 @@ func TestConsistentHashSelectExcludingByKey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIsValidAlgorithm(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
algorithm string
|
||||
@ -937,6 +948,7 @@ func TestIsValidAlgorithm(t *testing.T) {
|
||||
|
||||
// TestRoundRobin_SelectExcluding 测试轮询排除选择功能。
|
||||
func TestRoundRobin_SelectExcluding(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("空排除列表", func(_ *testing.T) {
|
||||
rr := NewRoundRobin()
|
||||
targets := []*Target{
|
||||
@ -1041,6 +1053,7 @@ func TestRoundRobin_SelectExcluding(t *testing.T) {
|
||||
|
||||
// TestWeightedRoundRobin_SelectExcluding 测试加权轮询排除选择功能。
|
||||
func TestWeightedRoundRobin_SelectExcluding(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("排除高权重目标", func(_ *testing.T) {
|
||||
wrr := NewWeightedRoundRobin()
|
||||
targets := []*Target{
|
||||
@ -1099,6 +1112,7 @@ func TestWeightedRoundRobin_SelectExcluding(t *testing.T) {
|
||||
|
||||
// TestLeastConnections_SelectExcluding 测试最少连接排除选择功能。
|
||||
func TestLeastConnections_SelectExcluding(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("排除连接最少的目标", func(_ *testing.T) {
|
||||
lc := NewLeastConnections()
|
||||
targets := []*Target{
|
||||
@ -1157,6 +1171,7 @@ func TestLeastConnections_SelectExcluding(t *testing.T) {
|
||||
|
||||
// TestIPHash_SelectExcluding 测试IP哈希排除选择功能。
|
||||
func TestIPHash_SelectExcluding(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("排除命中目标", func(_ *testing.T) {
|
||||
ih := NewIPHash()
|
||||
targets := []*Target{
|
||||
@ -1231,6 +1246,7 @@ func TestIPHash_SelectExcluding(t *testing.T) {
|
||||
|
||||
// TestFilterHealthyAndExclude 测试filterHealthyAndExclude辅助函数。
|
||||
func TestFilterHealthyAndExclude(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("基本过滤和排除", func(_ *testing.T) {
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", true),
|
||||
@ -1282,6 +1298,7 @@ func TestFilterHealthyAndExclude(t *testing.T) {
|
||||
|
||||
// TestTarget_Hostname 测试Target.Hostname方法。
|
||||
func TestTarget_Hostname(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("从URL提取主机名", func(_ *testing.T) {
|
||||
target := NewTargetFromConfig("http://example.com:8080/api", 1, 0, 0, 0, false, false, "")
|
||||
got := target.Hostname()
|
||||
@ -1321,6 +1338,7 @@ func TestTarget_Hostname(t *testing.T) {
|
||||
|
||||
// TestTarget_ResolvedIPs 测试Target.ResolvedIPs和SetResolvedIPs方法。
|
||||
func TestTarget_ResolvedIPs(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("未设置时返回nil", func(_ *testing.T) {
|
||||
target := &Target{URL: "http://example.com"}
|
||||
got := target.ResolvedIPs()
|
||||
@ -1362,6 +1380,7 @@ func TestTarget_ResolvedIPs(t *testing.T) {
|
||||
|
||||
// TestTarget_NeedsResolve 测试Target.NeedsResolve方法。
|
||||
func TestTarget_NeedsResolve(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("IP地址不需要解析", func(_ *testing.T) {
|
||||
target := NewTargetFromConfig("http://192.168.1.1:8080", 1, 0, 0, 0, false, false, "")
|
||||
if target.NeedsResolve(time.Minute) {
|
||||
@ -1397,6 +1416,7 @@ func TestTarget_NeedsResolve(t *testing.T) {
|
||||
|
||||
// TestTarget_LastResolved 测试Target.LastResolved方法。
|
||||
func TestTarget_LastResolved(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("未设置时返回零值", func(_ *testing.T) {
|
||||
target := &Target{URL: "http://example.com"}
|
||||
got := target.LastResolved()
|
||||
@ -1420,6 +1440,7 @@ func TestTarget_LastResolved(t *testing.T) {
|
||||
|
||||
// TestNewTargetFromConfig 测试NewTargetFromConfig函数。
|
||||
func TestNewTargetFromConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("创建健康目标", func(_ *testing.T) {
|
||||
target := NewTargetFromConfig("http://backend:8080", 5, 0, 0, 0, false, false, "")
|
||||
if target.URL != "http://backend:8080" {
|
||||
@ -1444,6 +1465,7 @@ func TestNewTargetFromConfig(t *testing.T) {
|
||||
|
||||
// TestConsistentHash_PrecomputeHashes 测试预计算哈希功能。
|
||||
func TestConsistentHash_PrecomputeHashes(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("预计算哈希值", func(_ *testing.T) {
|
||||
ch := NewConsistentHash(50, "ip")
|
||||
targets := []*Target{
|
||||
@ -1496,6 +1518,7 @@ func TestConsistentHash_PrecomputeHashes(t *testing.T) {
|
||||
|
||||
// TestLeastConnections_ConcurrentSelection 测试最少连接并发选择。
|
||||
func TestLeastConnections_ConcurrentSelection(t *testing.T) {
|
||||
t.Parallel()
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", true),
|
||||
createHealthyTarget("http://backend2:8080", true),
|
||||
@ -1517,6 +1540,7 @@ func TestLeastConnections_ConcurrentSelection(t *testing.T) {
|
||||
|
||||
// TestWeightedRoundRobin_ConcurrentSelection 测试加权轮询并发选择。
|
||||
func TestWeightedRoundRobin_ConcurrentSelection(t *testing.T) {
|
||||
t.Parallel()
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", true),
|
||||
createHealthyTarget("http://backend2:8080", true),
|
||||
@ -1539,6 +1563,7 @@ func TestWeightedRoundRobin_ConcurrentSelection(t *testing.T) {
|
||||
|
||||
// TestIPHash_ConcurrentSelection 测试IP哈希并发选择。
|
||||
func TestIPHash_ConcurrentSelection(t *testing.T) {
|
||||
t.Parallel()
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", true),
|
||||
createHealthyTarget("http://backend2:8080", true),
|
||||
@ -1561,6 +1586,7 @@ func TestIPHash_ConcurrentSelection(t *testing.T) {
|
||||
|
||||
// TestTarget_Hostname_IPURL 测试纯IP地址URL的主机名提取。
|
||||
func TestTarget_Hostname_IPURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
target := NewTargetFromConfig("http://10.0.0.1:8080", 1, 0, 0, 0, false, false, "")
|
||||
got := target.Hostname()
|
||||
if got != "10.0.0.1" {
|
||||
@ -1570,6 +1596,7 @@ func TestTarget_Hostname_IPURL(t *testing.T) {
|
||||
|
||||
// TestConsistentHash_SelectByKey_EmptyKey 测试空键选择行为。
|
||||
func TestConsistentHash_SelectByKey_EmptyKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
ch := NewConsistentHash(100, "ip")
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", true),
|
||||
@ -1584,6 +1611,7 @@ func TestConsistentHash_SelectByKey_EmptyKey(t *testing.T) {
|
||||
|
||||
// TestConsistentHash_RebuildWithAllUnhealthy 测试所有目标不健康时重建。
|
||||
func TestConsistentHash_RebuildWithAllUnhealthy(t *testing.T) {
|
||||
t.Parallel()
|
||||
ch := NewConsistentHash(10, "ip")
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", false),
|
||||
@ -1603,6 +1631,7 @@ func TestConsistentHash_RebuildWithAllUnhealthy(t *testing.T) {
|
||||
|
||||
// TestConsistentHash_GetStats 测试统计信息完整性。
|
||||
func TestConsistentHash_GetStats(t *testing.T) {
|
||||
t.Parallel()
|
||||
ch := NewConsistentHash(50, "uri")
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", true),
|
||||
@ -1626,6 +1655,7 @@ func TestConsistentHash_GetStats(t *testing.T) {
|
||||
|
||||
// TestConsistentHash_GetHashKey 测试哈希键配置获取。
|
||||
func TestConsistentHash_GetHashKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
hashKey string
|
||||
@ -1648,6 +1678,7 @@ func TestConsistentHash_GetHashKey(t *testing.T) {
|
||||
|
||||
// TestSelectExcluding_DynamicRebuild 测试SelectByKey触发的动态重建。
|
||||
func TestSelectExcluding_DynamicRebuild(t *testing.T) {
|
||||
t.Parallel()
|
||||
ch := NewConsistentHash(10, "ip")
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", true),
|
||||
@ -1663,6 +1694,7 @@ func TestSelectExcluding_DynamicRebuild(t *testing.T) {
|
||||
|
||||
// TestWeightedRoundRobin_NegativeWeight 测试负权重行为。
|
||||
func TestWeightedRoundRobin_NegativeWeight(t *testing.T) {
|
||||
t.Parallel()
|
||||
wrr := NewWeightedRoundRobin()
|
||||
targets := []*Target{
|
||||
createHealthyTarget("http://backend1:8080", true),
|
||||
@ -1692,6 +1724,7 @@ func TestWeightedRoundRobin_NegativeWeight(t *testing.T) {
|
||||
|
||||
// TestRoundRobin_NilTargets 测试nil切片输入。
|
||||
func TestRoundRobin_NilTargets(t *testing.T) {
|
||||
t.Parallel()
|
||||
rr := NewRoundRobin()
|
||||
got := rr.Select(nil)
|
||||
if got != nil {
|
||||
@ -1701,6 +1734,7 @@ func TestRoundRobin_NilTargets(t *testing.T) {
|
||||
|
||||
// TestLeastConnections_NilTargets 测试nil切片输入。
|
||||
func TestLeastConnections_NilTargets(t *testing.T) {
|
||||
t.Parallel()
|
||||
lc := NewLeastConnections()
|
||||
got := lc.Select(nil)
|
||||
if got != nil {
|
||||
@ -1709,6 +1743,7 @@ func TestLeastConnections_NilTargets(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTargetIsAvailable(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("healthy target is available", func(t *testing.T) {
|
||||
target := NewTargetFromConfig("http://localhost:8080", 1, 0, 0, 0, false, false, "")
|
||||
if !target.IsAvailable() {
|
||||
@ -1750,6 +1785,7 @@ func TestTargetIsAvailable(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTargetRecordFailure(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("record failure increments count", func(t *testing.T) {
|
||||
target := NewTargetFromConfig("http://localhost:8080", 1, 0, 3, 10*time.Second, false, false, "")
|
||||
count := target.RecordFailure()
|
||||
@ -1777,6 +1813,7 @@ func TestTargetRecordFailure(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTargetRecordSuccess(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("record success resets fail count", func(t *testing.T) {
|
||||
target := NewTargetFromConfig("http://localhost:8080", 1, 0, 3, 10*time.Second, false, false, "")
|
||||
target.RecordFailure()
|
||||
@ -1794,6 +1831,7 @@ func TestTargetRecordSuccess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFilterHealthyBackup(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("prefers non-backup targets", func(t *testing.T) {
|
||||
primary := NewTargetFromConfig("http://primary:8080", 1, 0, 0, 0, false, false, "")
|
||||
backup := NewTargetFromConfig("http://backup:8080", 1, 0, 0, 0, true, false, "")
|
||||
@ -1820,6 +1858,7 @@ func TestFilterHealthyBackup(t *testing.T) {
|
||||
|
||||
// TestConsistentHash_Select 测试一致性哈希 Select 方法(委托给 SelectByKey)。
|
||||
func TestConsistentHash_Select(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("委托给SelectByKey", func(_ *testing.T) {
|
||||
ch := NewConsistentHash(100, "ip")
|
||||
targets := []*Target{
|
||||
@ -1881,6 +1920,7 @@ func TestConsistentHash_Select(t *testing.T) {
|
||||
|
||||
// TestConsistentHash_SelectExcluding 测试一致性哈希 SelectExcluding 方法。
|
||||
func TestConsistentHash_SelectExcluding(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("委托给SelectExcludingByKey", func(_ *testing.T) {
|
||||
ch := NewConsistentHash(100, "ip")
|
||||
targets := []*Target{
|
||||
@ -1915,6 +1955,7 @@ func TestConsistentHash_SelectExcluding(t *testing.T) {
|
||||
|
||||
// TestRandomBalancer 测试随机负载均衡器。
|
||||
func TestRandomBalancer(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("selects from available targets", func(t *testing.T) {
|
||||
targets := []*Target{
|
||||
NewTargetFromConfig("http://a:8080", 1, 0, 0, 0, false, false, ""),
|
||||
|
||||
@ -28,6 +28,7 @@ import (
|
||||
)
|
||||
|
||||
func TestNewStatusHandler_CIDR(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
allow []string
|
||||
@ -80,6 +81,7 @@ func TestNewStatusHandler_CIDR(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewStatusHandler_SingleIP(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
allow []string
|
||||
@ -130,6 +132,7 @@ func TestNewStatusHandler_SingleIP(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewStatusHandler_InvalidIP(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
allow []string
|
||||
@ -164,6 +167,7 @@ func TestNewStatusHandler_InvalidIP(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_Path(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
cfgPath string
|
||||
@ -206,6 +210,7 @@ func TestStatusHandler_Path(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_checkAccess(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
clientIP string
|
||||
@ -292,6 +297,7 @@ func TestStatusHandler_checkAccess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_ServeHTTP_NoAllowList(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Allow: []string{},
|
||||
@ -318,6 +324,7 @@ func TestStatusHandler_ServeHTTP_NoAllowList(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetClientIPForStatus_XForwardedFor(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
xff string
|
||||
@ -360,6 +367,7 @@ func TestGetClientIPForStatus_XForwardedFor(t *testing.T) {
|
||||
// 在没有初始化连接的情况下,行为取决于 fasthttp 的默认值
|
||||
|
||||
func TestGetClientIPForStatus_XRealIP(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
xri string
|
||||
@ -393,6 +401,7 @@ func TestGetClientIPForStatus_XRealIP(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetClientIPForStatus_Priority(t *testing.T) {
|
||||
t.Parallel()
|
||||
// X-Forwarded-For 优先级高于 X-Real-IP
|
||||
ctx := &fasthttp.RequestCtx{}
|
||||
ctx.Request.Header.Set("X-Forwarded-For", "10.0.0.1")
|
||||
@ -407,6 +416,7 @@ func TestGetClientIPForStatus_Priority(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCollectStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
// 创建服务器实例用于测试
|
||||
srv := New(nil)
|
||||
srv.startTime = time.Now()
|
||||
@ -448,6 +458,7 @@ func TestCollectStatus(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCollectStatus_WithPool(t *testing.T) {
|
||||
t.Parallel()
|
||||
srv := New(nil)
|
||||
srv.startTime = time.Now()
|
||||
srv.pool = NewGoroutinePool(PoolConfig{
|
||||
@ -480,6 +491,7 @@ func TestCollectStatus_WithPool(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCollectStatus_WithFileCache(t *testing.T) {
|
||||
t.Parallel()
|
||||
srv := New(nil)
|
||||
srv.startTime = time.Now()
|
||||
|
||||
@ -503,6 +515,7 @@ func TestCollectStatus_WithFileCache(t *testing.T) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestStatusHandler_ServeHTTP_JSONFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "json",
|
||||
@ -556,6 +569,7 @@ func TestStatusHandler_ServeHTTP_JSONFormat(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_ServeHTTP_HTMLFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "html",
|
||||
@ -603,6 +617,7 @@ func TestStatusHandler_ServeHTTP_HTMLFormat(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_ServeHTTP_TextFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "text",
|
||||
@ -656,6 +671,7 @@ func TestStatusHandler_ServeHTTP_TextFormat(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_ServeHTTP_PrometheusFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "prometheus",
|
||||
@ -713,6 +729,7 @@ func TestStatusHandler_ServeHTTP_PrometheusFormat(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_ServeHTTP_DefaultFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Format 为空时应回退到 JSON
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
@ -749,6 +766,7 @@ func TestStatusHandler_ServeHTTP_DefaultFormat(t *testing.T) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestStatusHandler_ServeHTTP_AccessDenied(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "json",
|
||||
@ -776,6 +794,7 @@ func TestStatusHandler_ServeHTTP_AccessDenied(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_ServeHTTP_AccessAllowed_ByCIDR(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "json",
|
||||
@ -802,6 +821,7 @@ func TestStatusHandler_ServeHTTP_AccessAllowed_ByCIDR(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_New_localhost(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Allow: []string{"localhost"},
|
||||
@ -845,6 +865,7 @@ func TestStatusHandler_New_localhost(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_checkAccess_AllowList(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
allow []string
|
||||
@ -910,6 +931,7 @@ func TestStatusHandler_checkAccess_AllowList(t *testing.T) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestCollectStatus_WithFullData(t *testing.T) {
|
||||
t.Parallel()
|
||||
srv := New(nil)
|
||||
srv.startTime = time.Now()
|
||||
srv.connections.Store(42)
|
||||
@ -981,6 +1003,7 @@ func TestCollectStatus_WithFullData(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCollectStatus_NilServerFields(t *testing.T) {
|
||||
t.Parallel()
|
||||
srv := New(nil)
|
||||
srv.startTime = time.Now()
|
||||
// fileCache 和 pool 都为 nil
|
||||
@ -1005,6 +1028,7 @@ func TestCollectStatus_NilServerFields(t *testing.T) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestStatusHandler_ServeHTTP_HTMLWithAllSections(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "html",
|
||||
@ -1062,6 +1086,7 @@ func TestStatusHandler_ServeHTTP_HTMLWithAllSections(t *testing.T) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestStatusHandler_ServeHTTP_TextWithPool(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "text",
|
||||
@ -1105,6 +1130,7 @@ func TestStatusHandler_ServeHTTP_TextWithPool(t *testing.T) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestStatusHandler_ServeHTTP_PrometheusWithCache(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "prometheus",
|
||||
@ -1161,6 +1187,7 @@ func TestStatusHandler_ServeHTTP_PrometheusWithCache(t *testing.T) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestStatusHandler_ServeHTTP_AccessDenied_XForwardedFor(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "json",
|
||||
@ -1188,6 +1215,7 @@ func TestStatusHandler_ServeHTTP_AccessDenied_XForwardedFor(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatusHandler_ServeHTTP_AccessAllowed_XForwardedFor(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "json",
|
||||
@ -1218,6 +1246,7 @@ func TestStatusHandler_ServeHTTP_AccessAllowed_XForwardedFor(t *testing.T) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestServePrometheus_WithUpstreams(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "prometheus",
|
||||
@ -1281,6 +1310,7 @@ func TestServePrometheus_WithUpstreams(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServePrometheus_WithSSL(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "prometheus",
|
||||
@ -1326,6 +1356,7 @@ func TestServePrometheus_WithSSL(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServePrometheus_WithRateLimits(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "prometheus",
|
||||
@ -1383,6 +1414,7 @@ func TestServePrometheus_WithRateLimits(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServePrometheus_WithProxyCache(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "prometheus",
|
||||
@ -1438,6 +1470,7 @@ func TestServePrometheus_WithProxyCache(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServeJSON_WithFullStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "json",
|
||||
@ -1554,6 +1587,7 @@ func TestServeJSON_WithFullStatus(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServeText_WithAllSections(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "text",
|
||||
@ -1696,6 +1730,7 @@ func TestServeText_WithAllSections(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServeHTML_WithAllSections(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "html",
|
||||
@ -1853,6 +1888,7 @@ func TestServeHTML_WithAllSections(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServeText_WithEmptyUpstreams(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "text",
|
||||
@ -1889,6 +1925,7 @@ func TestServeText_WithEmptyUpstreams(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServeHTML_WithEmptyRateLimits(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "html",
|
||||
@ -1925,6 +1962,7 @@ func TestServeHTML_WithEmptyRateLimits(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServePrometheus_WithMultipleUpstreams(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "prometheus",
|
||||
@ -1984,6 +2022,7 @@ func TestServePrometheus_WithMultipleUpstreams(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServeText_WithCacheOnly(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "text",
|
||||
@ -2046,6 +2085,7 @@ func TestServeText_WithCacheOnly(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServeHTML_WithSSLAndRateLimits(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "html",
|
||||
@ -2114,6 +2154,7 @@ func TestServeHTML_WithSSLAndRateLimits(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServePrometheus_WithPool(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "prometheus",
|
||||
@ -2162,6 +2203,7 @@ func TestServePrometheus_WithPool(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServePrometheus_ZeroValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "prometheus",
|
||||
@ -2204,6 +2246,7 @@ func TestServePrometheus_ZeroValues(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServeText_ZeroValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "text",
|
||||
@ -2245,6 +2288,7 @@ func TestServeText_ZeroValues(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServeHTML_ZeroValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &config.StatusConfig{
|
||||
Path: "/_status",
|
||||
Format: "html",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user