179 lines
3.9 KiB
Go
179 lines
3.9 KiB
Go
package metrics
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestNewMetrics(t *testing.T) {
|
|
m := New()
|
|
if m.CacheHits == nil {
|
|
t.Error("expected CacheHits to be initialized")
|
|
}
|
|
if m.CacheMisses == nil {
|
|
t.Error("expected CacheMisses to be initialized")
|
|
}
|
|
if m.layerTTLs == nil {
|
|
t.Error("expected layerTTLs to be initialized")
|
|
}
|
|
if m.SearchDuration == nil {
|
|
t.Error("expected SearchDuration to be initialized")
|
|
}
|
|
if m.SearchDuration.maxValues != 1000 {
|
|
t.Errorf("expected maxValues 1000, got %d", m.SearchDuration.maxValues)
|
|
}
|
|
}
|
|
|
|
func TestMetricsRecordCacheHit(t *testing.T) {
|
|
m := New()
|
|
m.RecordCacheHit("search")
|
|
m.RecordCacheHit("search")
|
|
|
|
m.mu.Lock()
|
|
hits := m.CacheHits["search"]
|
|
m.mu.Unlock()
|
|
|
|
if hits != 2 {
|
|
t.Errorf("expected 2 cache hits, got %d", hits)
|
|
}
|
|
}
|
|
|
|
func TestMetricsRecordCacheMiss(t *testing.T) {
|
|
m := New()
|
|
m.RecordCacheMiss("search")
|
|
m.RecordCacheMiss("search")
|
|
|
|
m.mu.Lock()
|
|
misses := m.CacheMisses["search"]
|
|
m.mu.Unlock()
|
|
|
|
if misses != 2 {
|
|
t.Errorf("expected 2 cache misses, got %d", misses)
|
|
}
|
|
}
|
|
|
|
func TestMetricsRecordAPIQuota(t *testing.T) {
|
|
m := New()
|
|
m.RecordAPIQuota(1000)
|
|
|
|
m.mu.Lock()
|
|
quota := m.APIQuotaRemaining
|
|
m.mu.Unlock()
|
|
|
|
if quota != 1000 {
|
|
t.Errorf("expected API quota 1000, got %d", quota)
|
|
}
|
|
}
|
|
|
|
func TestMetricsRecordCircuitBreakerTrip(t *testing.T) {
|
|
m := New()
|
|
m.RecordCircuitBreakerTrip()
|
|
m.RecordCircuitBreakerTrip()
|
|
|
|
m.mu.Lock()
|
|
trips := m.CircuitBreakerTrips
|
|
m.mu.Unlock()
|
|
|
|
if trips != 2 {
|
|
t.Errorf("expected 2 circuit breaker trips, got %d", trips)
|
|
}
|
|
}
|
|
|
|
func TestMetricsRecordSearch(t *testing.T) {
|
|
m := New()
|
|
m.RecordSearch(1000000000) // 1 second in nanoseconds
|
|
m.RecordSearch(2000000000) // 2 seconds in nanoseconds
|
|
|
|
m.mu.Lock()
|
|
count := m.SearchCount
|
|
valuesLen := len(m.SearchDuration.values)
|
|
m.mu.Unlock()
|
|
|
|
if count != 2 {
|
|
t.Errorf("expected SearchCount 2, got %d", count)
|
|
}
|
|
if valuesLen != 2 {
|
|
t.Errorf("expected 2 duration values, got %d", valuesLen)
|
|
}
|
|
}
|
|
|
|
func TestMetricsRecordSearchTrim(t *testing.T) {
|
|
m := New()
|
|
m.SearchDuration.maxValues = 2
|
|
|
|
for i := 0; i < 5; i++ {
|
|
m.RecordSearch(int64(i * 1000000000))
|
|
}
|
|
|
|
m.mu.Lock()
|
|
valuesLen := len(m.SearchDuration.values)
|
|
m.mu.Unlock()
|
|
|
|
if valuesLen != 2 {
|
|
t.Errorf("expected 2 duration values after trim, got %d", valuesLen)
|
|
}
|
|
}
|
|
|
|
func TestMetricsGetCacheHitRate(t *testing.T) {
|
|
m := New()
|
|
m.RecordCacheHit("search")
|
|
m.RecordCacheHit("search")
|
|
m.RecordCacheMiss("search")
|
|
|
|
rate := m.GetCacheHitRate("search")
|
|
if rate != 0.6666666666666666 { // 2/3
|
|
t.Errorf("expected cache hit rate 0.6666666666666666, got %f", rate)
|
|
}
|
|
|
|
// Test with no data
|
|
rateEmpty := m.GetCacheHitRate("empty")
|
|
if rateEmpty != 0 {
|
|
t.Errorf("expected cache hit rate 0 for empty layer, got %f", rateEmpty)
|
|
}
|
|
}
|
|
|
|
func TestMetricsGetMetricsJSON(t *testing.T) {
|
|
m := New()
|
|
m.RecordCacheHit("search")
|
|
m.RecordCacheMiss("search")
|
|
m.RecordAPIQuota(500)
|
|
m.RecordCircuitBreakerTrip()
|
|
m.RecordSearch(1000000000)
|
|
|
|
json := m.GetMetricsJSON()
|
|
|
|
if json["cache_hits"] == nil {
|
|
t.Error("expected cache_hits in JSON")
|
|
}
|
|
if json["cache_misses"] == nil {
|
|
t.Error("expected cache_misses in JSON")
|
|
}
|
|
if json["api_quota_remaining"] != int64(500) {
|
|
t.Errorf("expected api_quota_remaining 500, got %v", json["api_quota_remaining"])
|
|
}
|
|
if json["circuit_breaker_trips"] != int64(1) {
|
|
t.Errorf("expected circuit_breaker_trips 1, got %v", json["circuit_breaker_trips"])
|
|
}
|
|
if json["search_count"] != int64(1) {
|
|
t.Errorf("expected search_count 1, got %v", json["search_count"])
|
|
}
|
|
}
|
|
|
|
func TestMetricsSetAndGetLayerTTL(t *testing.T) {
|
|
m := New()
|
|
m.SetLayerTTL("search", 3600*time.Second)
|
|
|
|
ttl, ok := m.GetLayerTTL("search")
|
|
if !ok {
|
|
t.Error("expected TTL to be found for 'search' layer")
|
|
}
|
|
if ttl != 3600*time.Second {
|
|
t.Errorf("expected TTL 3600s, got %v", ttl)
|
|
}
|
|
|
|
_, ok = m.GetLayerTTL("nonexistent")
|
|
if ok {
|
|
t.Error("expected TTL to not be found for 'nonexistent' layer")
|
|
}
|
|
}
|