lolly/internal/integration/proxy_integration_test.go
xfy f12ffd180f chore: release v0.4.0
- Update CHANGELOG.md for v0.4.0
- Update Makefile FALLBACK_VERSION to 0.4.0
- Fix lint warnings (godoc comments, goconst)
- Clean up code formatting
2026-06-09 15:59:36 +08:00

357 lines
8.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build integration
// proxy_integration_test.go - 代理集成测试L2 层,进程内)
//
// 测试反向代理的配置和创建逻辑。
// 实际的网络转发测试在 L3 E2E 测试中进行。
//
// 作者xfy
package integration
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"rua.plus/lolly/internal/config"
"rua.plus/lolly/internal/loadbalance"
"rua.plus/lolly/internal/proxy"
)
// TestProxyCreation 测试代理创建
func TestProxyCreation(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "round_robin",
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
Write: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{
URL: "http://127.0.0.1:8081",
Weight: 1,
MaxFails: 3,
},
}
p, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err, "failed to create proxy")
require.NotNil(t, p)
// 验证配置
assert.Equal(t, "round_robin", cfg.LoadBalance)
assert.Equal(t, 5*time.Second, cfg.Timeout.Connect)
assert.Equal(t, 10*time.Second, cfg.Timeout.Read)
}
// TestProxyRequestHeaders 测试请求头修改配置
func TestProxyRequestHeaders(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "round_robin",
Headers: config.ProxyHeaders{
SetRequest: map[string]string{
"X-Custom-Header": "custom-value",
"X-Forwarded-Proto": "https",
},
},
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
// 验证代理配置已设置
assert.NotNil(t, cfg.Headers.SetRequest)
assert.Equal(t, "custom-value", cfg.Headers.SetRequest["X-Custom-Header"])
assert.Equal(t, "https", cfg.Headers.SetRequest["X-Forwarded-Proto"])
}
// TestProxyResponseHeaders 测试响应头修改配置
func TestProxyResponseHeaders(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "round_robin",
Headers: config.ProxyHeaders{
SetResponse: map[string]string{
"X-Server": "lolly",
},
Remove: []string{"X-Powered-By"},
},
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
// 验证响应头配置
assert.Equal(t, "lolly", cfg.Headers.SetResponse["X-Server"])
assert.Contains(t, cfg.Headers.Remove, "X-Powered-By")
}
// TestProxyTimeout 测试代理超时配置
func TestProxyTimeout(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "round_robin",
Timeout: config.ProxyTimeout{
Connect: 1 * time.Second,
Read: 50 * time.Millisecond,
Write: 1 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
// 验证超时配置
assert.Equal(t, 1*time.Second, cfg.Timeout.Connect)
assert.Equal(t, 50*time.Millisecond, cfg.Timeout.Read)
assert.Equal(t, 1*time.Second, cfg.Timeout.Write)
}
// TestProxyLoadBalanceRoundRobin 测试轮询负载均衡配置
func TestProxyLoadBalanceRoundRobin(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "round_robin",
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
{URL: "http://127.0.0.1:8082", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
// 验证负载均衡器类型
assert.Equal(t, "round_robin", cfg.LoadBalance)
assert.Len(t, targets, 2)
}
// TestProxyWeightedRoundRobin 测试加权轮询配置
func TestProxyWeightedRoundRobin(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "weighted_round_robin",
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 3},
{URL: "http://127.0.0.1:8082", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
// 验证权重配置
assert.Equal(t, 3, targets[0].Weight)
assert.Equal(t, 1, targets[1].Weight)
}
// TestProxyLeastConn 测试最少连接负载均衡配置
func TestProxyLeastConn(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "least_conn",
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
{URL: "http://127.0.0.1:8082", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
assert.Equal(t, "least_conn", cfg.LoadBalance)
}
// TestProxyIPHash 测试 IP 哈希负载均衡配置
func TestProxyIPHash(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "ip_hash",
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
{URL: "http://127.0.0.1:8082", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
assert.Equal(t, "ip_hash", cfg.LoadBalance)
}
// TestProxyConsistentHash 测试一致性哈希负载均衡配置
func TestProxyConsistentHash(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "consistent_hash",
HashKey: "uri",
VirtualNodes: 150,
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
{URL: "http://127.0.0.1:8082", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
assert.Equal(t, "consistent_hash", cfg.LoadBalance)
assert.Equal(t, "uri", cfg.HashKey)
assert.Equal(t, 150, cfg.VirtualNodes)
}
// TestProxyErrorHandling 测试错误处理配置
func TestProxyErrorHandling(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "round_robin",
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{
URL: "http://127.0.0.1:8081",
Weight: 1,
MaxFails: 3,
FailTimeout: 10 * time.Second,
},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
// 验证 MaxFails 配置 (int64 类型)
assert.Equal(t, int64(3), targets[0].MaxFails)
assert.Equal(t, 10*time.Second, targets[0].FailTimeout)
}
// TestProxyCacheConfig 测试缓存配置
func TestProxyCacheConfig(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "round_robin",
Cache: config.ProxyCacheConfig{
Enabled: true,
MaxAge: 60 * time.Second,
Methods: []string{"GET", "HEAD"},
MinUses: 1,
CacheLock: true,
CacheLockTimeout: 5 * time.Second,
StaleWhileRevalidate: 30 * time.Second,
},
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
// 验证缓存配置
assert.True(t, cfg.Cache.Enabled)
assert.Equal(t, 60*time.Second, cfg.Cache.MaxAge)
assert.Contains(t, cfg.Cache.Methods, "GET")
assert.True(t, cfg.Cache.CacheLock)
}
// TestProxyNextUpstream 测试故障转移配置
func TestProxyNextUpstream(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "round_robin",
NextUpstream: config.NextUpstreamConfig{
Tries: 3,
HTTPCodes: []int{502, 503, 504},
},
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
{URL: "http://127.0.0.1:8082", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
// 验证故障转移配置
assert.Equal(t, 3, cfg.NextUpstream.Tries)
assert.Contains(t, cfg.NextUpstream.HTTPCodes, 502)
assert.Contains(t, cfg.NextUpstream.HTTPCodes, 503)
assert.Contains(t, cfg.NextUpstream.HTTPCodes, 504)
}
// TestProxyHealthCheck 测试健康检查配置
func TestProxyHealthCheck(t *testing.T) {
cfg := &config.ProxyConfig{
LoadBalance: "round_robin",
HealthCheck: config.HealthCheckConfig{
Interval: 10 * time.Second,
Path: "/health",
Timeout: 5 * time.Second,
},
Timeout: config.ProxyTimeout{
Connect: 5 * time.Second,
Read: 10 * time.Second,
},
}
targets := []*loadbalance.Target{
{URL: "http://127.0.0.1:8081", Weight: 1},
}
_, err := proxy.NewProxy(cfg, targets, nil, nil)
require.NoError(t, err)
// 验证健康检查配置
assert.Equal(t, 10*time.Second, cfg.HealthCheck.Interval)
assert.Equal(t, "/health", cfg.HealthCheck.Path)
assert.Equal(t, 5*time.Second, cfg.HealthCheck.Timeout)
}