mirror of
https://github.com/hhftechnology/middleware-manager.git
synced 2026-07-18 04:13:25 +00:00
add safety across services: whitelist tables for DeleteInTransaction to prevent dynamic-SQL deletion abuse; remove a deprecated UpdateInTransaction helper. centralize HTTP client creation (HTTPClientWithTimeout/GetHTTPClient) and replace ad-hoc http.Clients with it; limit response body reads with io.LimitReader to avoid unbounded memory use; add better error logging when JSON marshal fails. Improve ConfigProxy cache handling to fetch outside locks, return stale cache on fetch errors, and only lock to swap the cache; add locking to SetCacheDuration and cap error body reads. convert ResourceWatcher isRunning to atomic.Bool for safe concurrent start/stop. Replace sync.Map memoization in id_normalizer with a bounded map protected by RWMutex (maxCacheSize), add cache flush behavior and tests/benchmarks to validate boundedness and hits. Miscellaneous test updates to match new behavior.
109 lines
2.3 KiB
Go
109 lines
2.3 KiB
Go
package util
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func TestNormalizeID(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected string
|
|
}{
|
|
{"service@http", "service"},
|
|
{"service@docker", "service"},
|
|
{"my-app-auth-auth", "my-app-auth"},
|
|
{"my-app-router-auth-auth", "my-app-router-auth"},
|
|
{"my-app-router-redirect-auth", "my-app-router-redirect"},
|
|
{"simple-id", "simple-id"},
|
|
{"", ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
ClearNormalizationCache()
|
|
result := NormalizeID(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("NormalizeID(%q) = %q, want %q", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNormalizeIDCacheHit(t *testing.T) {
|
|
ClearNormalizationCache()
|
|
first := NormalizeID("test@http")
|
|
second := NormalizeID("test@http")
|
|
if first != second {
|
|
t.Errorf("cache returned different results: %q vs %q", first, second)
|
|
}
|
|
}
|
|
|
|
func TestCacheBoundedness(t *testing.T) {
|
|
ClearNormalizationCache()
|
|
|
|
// Fill cache beyond maxCacheSize
|
|
for i := 0; i < maxCacheSize+100; i++ {
|
|
NormalizeID(fmt.Sprintf("id-%d@http", i))
|
|
}
|
|
|
|
// Cache should have been flushed, so size <= maxCacheSize
|
|
cacheMu.RLock()
|
|
size := len(normalizedIDCache)
|
|
cacheMu.RUnlock()
|
|
|
|
if size > maxCacheSize {
|
|
t.Errorf("cache size %d exceeds max %d", size, maxCacheSize)
|
|
}
|
|
}
|
|
|
|
func TestClearNormalizationCache(t *testing.T) {
|
|
NormalizeID("something@http")
|
|
|
|
ClearNormalizationCache()
|
|
|
|
cacheMu.RLock()
|
|
size := len(normalizedIDCache)
|
|
cacheMu.RUnlock()
|
|
|
|
if size != 0 {
|
|
t.Errorf("cache not empty after clear: %d entries", size)
|
|
}
|
|
}
|
|
|
|
func TestGetProviderSuffix(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected string
|
|
}{
|
|
{"service@http", "@http"},
|
|
{"service@docker", "@docker"},
|
|
{"no-suffix", ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
result := GetProviderSuffix(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("GetProviderSuffix(%q) = %q, want %q", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkNormalizeIDUnique(b *testing.B) {
|
|
ClearNormalizationCache()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
NormalizeID(fmt.Sprintf("unique-id-%d@http", i))
|
|
}
|
|
}
|
|
|
|
func BenchmarkNormalizeIDRepeated(b *testing.B) {
|
|
ClearNormalizationCache()
|
|
NormalizeID("repeated-id@http")
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
NormalizeID("repeated-id@http")
|
|
}
|
|
}
|