lolly/internal/lua/api_balancer_test.go
xfy 9144dcbb06 refactor(server): 提取初始化逻辑到独立函数
- 将 Start() 中的 goroutine pool 初始化提取为 initGoroutinePool()
- 将 file cache 初始化提取为 initFileCache()
- 将 Lua engine 初始化提取为 initLuaEngine()
- 将 error page manager 初始化提取为 initErrorPageManager()
- 添加 init.go 存放提取的初始化函数
- 添加 init_test.go 测试初始化函数
- 添加 testutil.go 提供测试 mock 和工具
- 添加 lua_integration_test.go Lua 中间件集成测试
- 添加 start_integration_test.go Start() 集成测试
- 添加 server_test.go nil tlsManager 测试
- 添加 lua/mock_engine.go Lua 引擎 mock 实现
- 添加 lua/api_balancer_test.go Lua balancer API 测试

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 17:38:49 +08:00

162 lines
3.6 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.

// Package lua 提供 ngx.balancer API 的测试
//
// 该文件测试负载均衡相关的 Lua API包括
// - BalancerContext 创建和管理
// - set_current_peer API
// - set_more_tries API
// - get_last_failure API
// - get_targets API
// - get_client_ip API
// - IsSelected 边界测试
//
// 作者xfy
package lua
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
"rua.plus/lolly/internal/loadbalance"
)
// TestBalancerContext_IsSelected 测试 IsSelected 方法
func TestBalancerContext_IsSelected(t *testing.T) {
tests := []struct {
name string
selected bool
wantResult bool
}{
{
name: "已选择目标",
selected: true,
wantResult: true,
},
{
name: "未选择目标",
selected: false,
wantResult: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
bctx := &BalancerContext{
Targets: []*loadbalance.Target{
{URL: "http://backend1:8080"},
{URL: "http://backend2:8080"},
},
ClientIP: "127.0.0.1",
Retries: 3,
selected: tt.selected,
}
if tt.selected {
bctx.Selected = bctx.Targets[0]
}
result := bctx.IsSelected()
assert.Equal(t, tt.wantResult, result, "IsSelected() should return expected value")
})
}
}
// TestBalancerContext_IsSelected_ZeroValue 测试零值情况
func TestBalancerContext_IsSelected_ZeroValue(t *testing.T) {
// 零值的 BalancerContext
bctx := &BalancerContext{}
// 默认应该返回 false
result := bctx.IsSelected()
assert.False(t, result, "Zero value BalancerContext should return false for IsSelected()")
}
// TestBalancerContext_IsSelected_AfterSelection 测试选择后的状态
func TestBalancerContext_IsSelected_AfterSelection(t *testing.T) {
targets := []*loadbalance.Target{
{URL: "http://backend1:8080"},
{URL: "http://backend2:8080"},
}
bctx := &BalancerContext{
Targets: targets,
ClientIP: "192.168.1.1",
Retries: 3,
}
// 初始状态
assert.False(t, bctx.IsSelected(), "Should not be selected initially")
// 模拟选择目标
bctx.Selected = targets[0]
bctx.selected = true
// 选择后状态
assert.True(t, bctx.IsSelected(), "Should be selected after setting")
// 清除选择
bctx.selected = false
assert.False(t, bctx.IsSelected(), "Should not be selected after clearing flag")
}
// TestClassifyError 测试错误分类函数
func TestClassifyError(t *testing.T) {
tests := []struct {
name string
err error
expected string
}{
{
name: "nil error",
err: nil,
expected: "",
},
{
name: "timeout error",
err: errors.New("connection timeout"),
expected: "timeout",
},
{
name: "connection error",
err: errors.New("connection refused"),
expected: "failed",
},
{
name: "generic error",
err: errors.New("some error"),
expected: "failed",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := classifyError(tt.err)
assert.Equal(t, tt.expected, result)
})
}
}
// TestBalancerContext_Structure 测试 BalancerContext 结构体字段
func TestBalancerContext_Structure(t *testing.T) {
targets := []*loadbalance.Target{
{URL: "http://backend1:8080", Weight: 1},
{URL: "http://backend2:8080", Weight: 2},
}
bctx := &BalancerContext{
Targets: targets,
ClientIP: "10.0.0.1",
Retries: 5,
Selected: nil,
LastError: nil,
selected: false,
}
assert.Equal(t, 2, len(bctx.Targets))
assert.Equal(t, "10.0.0.1", bctx.ClientIP)
assert.Equal(t, 5, bctx.Retries)
assert.Nil(t, bctx.Selected)
assert.Nil(t, bctx.LastError)
assert.False(t, bctx.selected)
}