Files
AIRouter/internal/context/context_test.go
T
freedakgmail 93a469061d
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled
CI / security-scan (push) Has been cancelled
初始提交:边缘AI算力机统一AI通讯层
2026-08-03 07:44:05 +08:00

131 lines
3.4 KiB
Go

package context
import (
"testing"
"github.com/edgeai/gateway/internal/config"
"github.com/edgeai/gateway/pkg/api"
)
func TestTokenEstimator(t *testing.T) {
est := NewTokenEstimator()
// Empty string
if got := est.EstimateText(""); got != 0 {
t.Errorf("empty string: expected 0, got %d", got)
}
// English text
tokens := est.EstimateText("Hello world, this is a test.")
if tokens <= 0 {
t.Errorf("expected positive tokens for English, got %d", tokens)
}
// Chinese text (each char ~1 token)
cjkTokens := est.EstimateText("你好世界")
if cjkTokens != 4 {
t.Errorf("expected 4 tokens for 4 CJK chars, got %d", cjkTokens)
}
}
func TestEstimateKVCache(t *testing.T) {
// 1000 tokens, 32 layers, 4096 hidden dim, 2 bytes/element
result := EstimateKVCache(1000, 32, 4096, 2)
expected := int64(1000) * 32 * 2 * 4096 * 2
if result != expected {
t.Errorf("expected %d, got %d", expected, result)
}
}
func TestAssemblerNoTrim(t *testing.T) {
cfg := &config.ContextConfig{SafetyMarginRatio: 0.08}
a := NewAssembler(cfg)
history := []api.Message{
{Role: "user", Content: "Hi"},
{Role: "assistant", Content: "Hello!"},
}
newMsgs := []api.Message{
{Role: "user", Content: "How are you?"},
}
result := a.Assemble(history, newMsgs, 1000, 100, "summary_and_recent")
if result.Trimmed {
t.Error("expected no trimming for small context")
}
if len(result.Messages) != 3 {
t.Errorf("expected 3 messages, got %d", len(result.Messages))
}
}
func TestAssemblerTrimRecentOnly(t *testing.T) {
cfg := &config.ContextConfig{SafetyMarginRatio: 0.08}
a := NewAssembler(cfg)
// Create many messages that exceed budget
msgs := make([]api.Message, 20)
for i := range msgs {
msgs[i] = api.Message{Role: "user", Content: "This is message number " + string(rune('A'+i))}
}
result := a.Assemble(msgs, []api.Message{}, 50, 10, "recent_only")
if !result.Trimmed {
t.Error("expected trimming for large context")
}
if len(result.Messages) >= 20 {
t.Error("expected fewer messages after trimming")
}
}
func TestAssemblerSummaryAndRecent(t *testing.T) {
cfg := &config.ContextConfig{SafetyMarginRatio: 0.08}
a := NewAssembler(cfg)
msgs := make([]api.Message, 0, 22)
msgs = append(msgs, api.Message{Role: "system", Content: "You are a helpful assistant."})
for i := 0; i < 20; i++ {
msgs = append(msgs, api.Message{Role: "user", Content: "Message " + string(rune('A'+i%26))})
msgs = append(msgs, api.Message{Role: "assistant", Content: "Response " + string(rune('A'+i%26))})
}
result := a.Assemble(msgs, []api.Message{}, 80, 20, "summary_and_recent")
if !result.Trimmed {
t.Error("expected trimming")
}
// System message should be preserved
hasSystem := false
hasSummary := false
for _, m := range result.Messages {
if m.Role == "system" {
if content, ok := m.Content.(string); ok {
if content == "You are a helpful assistant." {
hasSystem = true
}
if contains(content, "summarized") {
hasSummary = true
}
}
}
}
if !hasSystem {
t.Error("system message should be preserved")
}
if !hasSummary {
t.Error("summary placeholder should be present when trimmed")
}
}
func contains(s, substr string) bool {
return len(s) >= len(substr) && (s == substr || (len(s) > len(substr) && (indexOf(s, substr) >= 0)))
}
func indexOf(s, substr string) int {
for i := 0; i <= len(s)-len(substr); i++ {
if s[i:i+len(substr)] == substr {
return i
}
}
return -1
}