Files
v-hono/tests/test_enhanced_fast_router.v
T

435 lines
10 KiB
V

import hono
import time
import net.http
fn main() {
println('=== 增强版 FastRouter 功能测试 ===')
// 测试1: 基本功能测试
test_basic_functionality()
// 测试2: LRU 缓存功能测试
test_lru_cache_functionality()
// 测试3: 路由复杂度排序测试
test_route_complexity_sorting()
// 测试4: 高级缓存管理测试
test_advanced_cache_management()
// 测试5: 性能对比测试
test_performance_comparison()
// 测试6: 健康检查测试
test_health_check()
// 测试7: 智能预热测试
test_smart_warmup()
println('\n🎯 增强版 FastRouter 测试完成')
}
fn test_basic_functionality() {
println('\n📊 基本功能测试...')
mut router := hono.FastRouter.new()
// 添加静态路由
static_handler := hono.ContextHandler{
path: '/static'
handler: fn (mut c hono.Context) http.Response {
return c.text('static')
}
}
router.add_route('GET', static_handler, '') or {
println(' ❌ 添加静态路由失败: ${err}')
return
}
// 添加动态路由
dynamic_handler := hono.ContextHandler{
path: '/users/:id'
handler: fn (mut c hono.Context) http.Response {
return c.text('dynamic')
}
}
router.add_route('GET', dynamic_handler, '') or {
println(' ❌ 添加动态路由失败: ${err}')
return
}
// 测试静态路由匹配
if _ := router.match_route('GET', '/static') {
println(' ✅ 静态路由匹配成功')
} else {
println(' ❌ 静态路由匹配失败')
}
// 测试动态路由匹配
if match_result := router.match_route('GET', '/users/123') {
println(' ✅ 动态路由匹配成功')
if match_result.params['id'] == '123' {
println(' ✅ 参数提取正确: id=${match_result.params['id']}')
} else {
println(' ❌ 参数提取错误')
}
} else {
println(' ❌ 动态路由匹配失败')
}
// 显示基本统计
static_count, dynamic_count, cache_count := router.get_stats()
println(' 📈 统计: 静态=${static_count}, 动态=${dynamic_count}, 缓存=${cache_count}')
}
fn test_lru_cache_functionality() {
println('\n📊 LRU 缓存功能测试...')
// 创建小缓存容量的路由器
mut router := hono.FastRouter.new_with_cache_size(3)
// 添加测试路由
for i in 0 .. 5 {
handler := hono.ContextHandler{
path: '/test${i}/:id'
handler: fn (mut c hono.Context) http.Response {
return c.text('test')
}
}
router.add_route('GET', handler, '') or {
continue
}
}
// 测试缓存填充
test_paths := ['/test0/123', '/test1/456', '/test2/789', '/test3/101', '/test4/202']
for path in test_paths {
router.match_route('GET', path)
}
cache_size, cache_capacity := router.get_cache_stats()
println(' 📈 缓存状态: ${cache_size}/${cache_capacity}')
if cache_size <= 3 {
println(' ✅ LRU 缓存容量限制正常工作')
} else {
println(' ❌ LRU 缓存容量限制失效')
}
// 测试缓存命中
start_time := time.now()
for _ in 0 .. 1000 {
router.match_route('GET', '/test4/202') // 应该命中缓存
}
cache_hit_time := time.since(start_time)
// 清理缓存后测试
router.clear_cache()
start_time2 := time.now()
for _ in 0 .. 1000 {
router.match_route('GET', '/test4/202') // 不会命中缓存
}
no_cache_time := time.since(start_time2)
println(' ⏱️ 缓存命中时间: ${cache_hit_time}')
println(' ⏱️ 无缓存时间: ${no_cache_time}')
if cache_hit_time < no_cache_time {
improvement := f64(no_cache_time.microseconds()) / f64(cache_hit_time.microseconds())
println(' 🚀 缓存性能提升: ${improvement:.2f}x')
}
}
fn test_route_complexity_sorting() {
println('\n📊 路由复杂度排序测试...')
mut router := hono.FastRouter.new()
// 添加不同复杂度的路由
routes := [
'/simple/:id', // 简单路由
'/complex/:category/:subcategory/:id', // 复杂路由
'/very/complex/:a/:b/:c/:d/:e', // 非常复杂
'/static/path', // 静态路由
'/medium/:type/:id' // 中等复杂度
]
for route in routes {
handler := hono.ContextHandler{
path: route
handler: fn (mut c hono.Context) http.Response {
return c.text('test')
}
}
router.add_route('GET', handler, '') or {
continue
}
}
// 获取路由按复杂度分组
simple_routes, complex_routes := router.get_routes_by_complexity()
println(' 📊 路由复杂度分布:')
println(' 简单路由 (≤30): ${simple_routes.len}')
for route in simple_routes {
println(' ${route.pattern} (复杂度: ${route.complexity})')
}
println(' 复杂路由 (>30): ${complex_routes.len}')
for route in complex_routes {
println(' ${route.pattern} (复杂度: ${route.complexity})')
}
// 验证排序是否正确
mut is_sorted := true
for i in 1 .. router.precompiled_routes.len {
if router.precompiled_routes[i-1].complexity > router.precompiled_routes[i].complexity {
is_sorted = false
break
}
}
if is_sorted {
println(' ✅ 路由按复杂度正确排序')
} else {
println(' ❌ 路由排序有误')
}
}
fn test_advanced_cache_management() {
println('\n📊 高级缓存管理测试...')
mut router := hono.FastRouter.new()
// 添加测试路由
handler := hono.ContextHandler{
path: '/test/:id'
handler: fn (mut c hono.Context) http.Response {
return c.text('test')
}
}
router.add_route('GET', handler, '') or {
println(' ❌ 添加路由失败')
return
}
// 设置短 TTL 进行测试
router.set_cache_ttl(1) // 1秒 TTL
// 填充缓存
router.match_route('GET', '/test/123')
cache_size1, _ := router.get_cache_stats()
println(' 📈 缓存填充后: ${cache_size1} 条目')
// 等待 TTL 过期
time.sleep(1100 * time.millisecond)
// 强制清理过期条目
router.force_cleanup_expired()
cache_size2, _ := router.get_cache_stats()
println(' 📈 TTL 清理后: ${cache_size2} 条目')
if cache_size2 < cache_size1 {
println(' ✅ TTL 过期清理正常工作')
} else {
println(' ⚠️ TTL 过期清理可能未生效')
}
// 测试缓存健康检查
if router.is_healthy() {
println(' ✅ 缓存健康状态正常')
} else {
println(' ❌ 缓存健康状态异常')
}
// 测试详细统计
detailed_stats := router.get_detailed_stats()
println(' 📊 详细统计:')
for key, value in detailed_stats {
println(' ${key}: ${value}')
}
}
fn test_performance_comparison() {
println('\n📊 性能对比测试...')
// 创建增强版 FastRouter
mut enhanced_router := hono.FastRouter.new()
// 创建原始 HybridRouter 进行对比
mut hybrid_router := hono.ContextHybridRouter.new()
// 添加相同的路由
test_routes := [
'/users/:id',
'/posts/:post_id/comments/:comment_id',
'/api/:version/users/:user_id',
'/files/:category/:filename',
'/admin/:module/:action/:id'
]
for route in test_routes {
enhanced_handler := hono.ContextHandler{
path: route
handler: fn (mut c hono.Context) http.Response {
return c.text('enhanced')
}
}
enhanced_router.add_route('GET', enhanced_handler, '') or {
continue
}
hybrid_handler := hono.ContextHandler{
path: route
handler: fn (mut c hono.Context) http.Response {
return c.text('hybrid')
}
}
hybrid_router.add_route('GET', hybrid_handler, '')
}
// 测试路径
test_paths := [
'/users/123',
'/posts/456/comments/789',
'/api/v1/users/101',
'/files/images/photo.jpg',
'/admin/users/edit/555'
]
iterations := 5000
// 测试增强版 FastRouter
start_time1 := time.now()
mut enhanced_matches := 0
for _ in 0 .. iterations {
for path in test_paths {
if _ := enhanced_router.match_route('GET', path) {
enhanced_matches++
}
}
}
enhanced_time := time.since(start_time1)
// 测试原始 HybridRouter
start_time2 := time.now()
mut hybrid_matches := 0
for _ in 0 .. iterations {
for path in test_paths {
if _ := hybrid_router.match_route('GET', path) {
hybrid_matches++
}
}
}
hybrid_time := time.since(start_time2)
println(' ⏱️ 增强版 FastRouter: ${enhanced_time} (${enhanced_matches} 匹配)')
println(' ⏱️ 原始 HybridRouter: ${hybrid_time} (${hybrid_matches} 匹配)')
if enhanced_matches > 0 && hybrid_matches > 0 {
enhanced_avg := f64(enhanced_time.microseconds()) / f64(enhanced_matches)
hybrid_avg := f64(hybrid_time.microseconds()) / f64(hybrid_matches)
if hybrid_avg > enhanced_avg {
improvement := hybrid_avg / enhanced_avg
println(' 🚀 增强版性能提升: ${improvement:.2f}x')
} else {
println(' ⚠️ 性能提升不明显')
}
}
}
fn test_health_check() {
println('\n📊 健康检查测试...')
mut router := hono.FastRouter.new()
// 添加一些路由
for i in 0 .. 10 {
handler := hono.ContextHandler{
path: '/test${i}/:id'
handler: fn (mut c hono.Context) http.Response {
return c.text('test')
}
}
router.add_route('GET', handler, '') or {
continue
}
}
// 填充缓存
for i in 0 .. 10 {
router.match_route('GET', '/test${i}/123')
}
// 检查健康状态
if router.is_healthy() {
println(' ✅ 路由器健康状态正常')
} else {
println(' ❌ 路由器健康状态异常')
}
// 显示完整性能分析
router.analyze_performance()
}
fn test_smart_warmup() {
println('\n📊 智能预热测试...')
mut router := hono.FastRouter.new()
// 添加不同复杂度的路由
routes := [
'/simple/:id',
'/complex/:a/:b/:c',
'/very/complex/:w/:x/:y/:z',
'/medium/:type/:id'
]
for route in routes {
handler := hono.ContextHandler{
path: route
handler: fn (mut c hono.Context) http.Response {
return c.text('test')
}
}
router.add_route('GET', handler, '') or {
continue
}
}
// 准备样本路径
sample_paths := [
'/simple/123',
'/complex/a/b/c',
'/very/complex/w/x/y/z',
'/medium/type1/456'
]
// 执行智能预热
router.smart_warmup(sample_paths)
// 检查预热效果
cache_size, _ := router.get_cache_stats()
println(' 📈 预热后缓存大小: ${cache_size}')
if cache_size > 0 {
println(' ✅ 智能预热成功')
} else {
println(' ⚠️ 智能预热效果不明显')
}
// 测试预热后的性能
start_time := time.now()
for _ in 0 .. 1000 {
for path in sample_paths {
router.match_route('GET', path)
}
}
warmed_time := time.since(start_time)
println(' ⏱️ 预热后性能: ${warmed_time}')
}