mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 10:06:24 +05:00
Add coverage tests for ips & statmetrics
This commit is contained in:
committed by
Dan Christian Bogos
parent
9ef9684a3d
commit
d6b8c8386e
@@ -20,9 +20,11 @@ package engine
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"slices"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
@@ -482,3 +484,209 @@ func TestIPRecordUsage(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestIPClearUsage(t *testing.T) {
|
||||
t.Run("usage not found", func(t *testing.T) {
|
||||
ip := &IP{Usages: make(map[string]*IPUsage)}
|
||||
err := ip.clearUsage("missing")
|
||||
if err == nil {
|
||||
t.Fatal("expected error, got nil")
|
||||
}
|
||||
expected := "cannot find usage record with id: missing"
|
||||
if err.Error() != expected {
|
||||
t.Errorf("expected error %q, got %q", expected, err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("usage found with zero expiry time", func(t *testing.T) {
|
||||
totalUsage := 10.0
|
||||
ip := &IP{
|
||||
Usages: map[string]*IPUsage{
|
||||
"id1": {Units: 5.0},
|
||||
},
|
||||
tUsage: &totalUsage,
|
||||
TTLIdx: []string{"id2"},
|
||||
}
|
||||
|
||||
err := ip.clearUsage("id1")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if _, exists := ip.Usages["id1"]; exists {
|
||||
t.Error("expected id1 to be deleted from Usages")
|
||||
}
|
||||
if *ip.tUsage != 5.0 {
|
||||
t.Errorf("expected tUsage=5.0, got %v", *ip.tUsage)
|
||||
}
|
||||
if !slices.Equal(ip.TTLIdx, []string{"id2"}) {
|
||||
t.Errorf("TTLIdx changed unexpectedly: %v", ip.TTLIdx)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("usage found with non-zero expiry time", func(t *testing.T) {
|
||||
totalUsage := 20.0
|
||||
expTime := time.Now().Add(time.Hour)
|
||||
ip := &IP{
|
||||
Usages: map[string]*IPUsage{
|
||||
"id2": {ExpiryTime: expTime, Units: 7.0},
|
||||
},
|
||||
TTLIdx: []string{"id2", "other"},
|
||||
tUsage: &totalUsage,
|
||||
}
|
||||
|
||||
err := ip.clearUsage("id2")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if _, exists := ip.Usages["id2"]; exists {
|
||||
t.Error("expected id2 to be deleted from Usages")
|
||||
}
|
||||
if *ip.tUsage != 13.0 {
|
||||
t.Errorf("expected tUsage=13.0, got %v", *ip.tUsage)
|
||||
}
|
||||
if slices.Contains(ip.TTLIdx, "id2") {
|
||||
t.Errorf("expected id2 to be removed from TTLIdx, got %v", ip.TTLIdx)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestIPsSort(t *testing.T) {
|
||||
ip1 := &IP{cfg: &IPProfile{Weight: 1.0}}
|
||||
ip2 := &IP{cfg: &IPProfile{Weight: 3.0}}
|
||||
ip3 := &IP{cfg: &IPProfile{Weight: 2.0}}
|
||||
|
||||
ips := IPs{ip1, ip2, ip3}
|
||||
ips.Sort()
|
||||
|
||||
expected := IPs{ip2, ip3, ip1}
|
||||
for i := range ips {
|
||||
if ips[i] != expected[i] {
|
||||
t.Errorf("expected index %d to be %+v, got %+v", i, expected[i], ips[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPsUnlock(t *testing.T) {
|
||||
ip1 := &IP{lkID: "lock1", cfg: &IPProfile{lkID: "cfgLock1"}}
|
||||
ip2 := &IP{lkID: "lock2", cfg: &IPProfile{lkID: "cfgLock2"}}
|
||||
ip3 := &IP{lkID: "lock3", cfg: nil}
|
||||
|
||||
ips := IPs{ip1, ip2, ip3}
|
||||
ips.unlock()
|
||||
|
||||
if ip1.lkID != "" {
|
||||
t.Errorf("expected ip1.lkID to be empty, got %q", ip1.lkID)
|
||||
}
|
||||
if ip2.lkID != "" {
|
||||
t.Errorf("expected ip2.lkID to be empty, got %q", ip2.lkID)
|
||||
}
|
||||
if ip3.lkID != "" {
|
||||
t.Errorf("expected ip3.lkID to be empty, got %q", ip3.lkID)
|
||||
}
|
||||
|
||||
if ip1.cfg.lkID != "" {
|
||||
t.Errorf("expected ip1.cfg.lkID to be empty, got %q", ip1.cfg.lkID)
|
||||
}
|
||||
if ip2.cfg.lkID != "" {
|
||||
t.Errorf("expected ip2.cfg.lkID to be empty, got %q", ip2.cfg.lkID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPsIds(t *testing.T) {
|
||||
ip1 := &IP{ID: "ip1"}
|
||||
ip2 := &IP{ID: "ip2"}
|
||||
ip3 := &IP{ID: "ip3"}
|
||||
|
||||
ips := IPs{ip1, ip2, ip3}
|
||||
|
||||
got := ips.ids()
|
||||
|
||||
if len(got) != 3 {
|
||||
t.Errorf("expected 3 IDs in set, got %d", len(got))
|
||||
}
|
||||
|
||||
expectedIDs := []string{"ip1", "ip2", "ip3"}
|
||||
for _, id := range expectedIDs {
|
||||
if _, exists := got[id]; !exists {
|
||||
t.Errorf("expected ID %q in set, but it was missing", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPCacheClone(t *testing.T) {
|
||||
ttl := 10 * time.Minute
|
||||
tUsage := 123.45
|
||||
dirty := true
|
||||
|
||||
original := &IP{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ip01",
|
||||
TTLIdx: []string{"idx1", "idx2"},
|
||||
Usages: map[string]*IPUsage{
|
||||
"u1": {Tenant: "cgrates.org", ID: "u1", Units: 50.0},
|
||||
},
|
||||
ttl: &ttl,
|
||||
tUsage: &tUsage,
|
||||
dirty: &dirty,
|
||||
cfg: &IPProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "profile1",
|
||||
Weight: 1.5,
|
||||
},
|
||||
}
|
||||
|
||||
cloneAny := original.CacheClone()
|
||||
if cloneAny == nil {
|
||||
t.Fatal("CacheClone returned nil")
|
||||
}
|
||||
|
||||
clone, ok := cloneAny.(*IP)
|
||||
if !ok {
|
||||
t.Fatalf("expected type *IP, got %T", cloneAny)
|
||||
}
|
||||
|
||||
if clone == original {
|
||||
t.Error("expected clone to be a different pointer than original")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(clone, original) {
|
||||
t.Errorf("expected clone to be deeply equal to original:\noriginal: %+v\nclone: %+v", original, clone)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewIPService(t *testing.T) {
|
||||
dm := &DataManager{}
|
||||
cgrcfg := &config.CGRConfig{}
|
||||
filterS := &FilterS{}
|
||||
connMgr := &ConnManager{}
|
||||
|
||||
service := NewIPService(dm, cgrcfg, filterS, connMgr)
|
||||
if service == nil {
|
||||
t.Fatal("expected NewIPService to return non-nil")
|
||||
}
|
||||
|
||||
if service.dm != dm {
|
||||
t.Errorf("expected dm=%+v, got %+v", dm, service.dm)
|
||||
}
|
||||
if service.cfg != cgrcfg {
|
||||
t.Errorf("expected cfg=%+v, got %+v", cgrcfg, service.cfg)
|
||||
}
|
||||
if service.fs != filterS {
|
||||
t.Errorf("expected fs=%+v, got %+v", filterS, service.fs)
|
||||
}
|
||||
if service.cm != connMgr {
|
||||
t.Errorf("expected cm=%+v, got %+v", connMgr, service.cm)
|
||||
}
|
||||
|
||||
if service.storedIPs == nil {
|
||||
t.Error("expected storedIPs map to be initialized")
|
||||
}
|
||||
if service.loopStopped == nil {
|
||||
t.Error("expected loopStopped channel to be initialized")
|
||||
}
|
||||
if service.stopBackup == nil {
|
||||
t.Error("expected stopBackup channel to be initialized")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6324,3 +6324,107 @@ func TestStatREPSCGetFloat64Value(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewStatREPSC(t *testing.T) {
|
||||
filterIDs := []string{"fltr1", "fltr2"}
|
||||
minItems := 5
|
||||
|
||||
metric, err := NewStatREPSC(minItems, "ignored", filterIDs)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error, got %v", err)
|
||||
}
|
||||
|
||||
stat, ok := metric.(*StatREPSC)
|
||||
if !ok {
|
||||
t.Fatalf("expected type *StatREPSC, got %T", metric)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(stat.FilterIDs, filterIDs) {
|
||||
t.Errorf("expected FilterIDs %v, got %v", filterIDs, stat.FilterIDs)
|
||||
}
|
||||
|
||||
if stat.MinItems != minItems {
|
||||
t.Errorf("expected MinItems %d, got %d", minItems, stat.MinItems)
|
||||
}
|
||||
|
||||
if stat.Events == nil {
|
||||
t.Error("expected Events map to be initialized, got nil")
|
||||
} else if len(stat.Events) != 0 {
|
||||
t.Errorf("expected Events to be empty, got length %d", len(stat.Events))
|
||||
}
|
||||
|
||||
if stat.Count != 0 {
|
||||
t.Errorf("expected Count 0, got %d", stat.Count)
|
||||
}
|
||||
|
||||
if stat.cachedVal != nil {
|
||||
t.Errorf("expected cachedVal to be nil, got %v", stat.cachedVal)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatREPSCGetStringValue(t *testing.T) {
|
||||
t.Run("returns NotAvailable when StatsNA", func(t *testing.T) {
|
||||
s := &StatREPSC{}
|
||||
na := utils.StatsNA
|
||||
s.cachedVal = &na
|
||||
got := s.GetStringValue(2)
|
||||
if got != utils.NotAvailable {
|
||||
t.Errorf("expected %q, got %q", utils.NotAvailable, got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("returns formatted float when value is not StatsNA", func(t *testing.T) {
|
||||
s := &StatREPSC{}
|
||||
val := 123.456
|
||||
s.cachedVal = &val
|
||||
|
||||
got := s.GetStringValue(2)
|
||||
expected := strconv.FormatFloat(val, 'f', -1, 64)
|
||||
if got != expected {
|
||||
t.Errorf("expected %q, got %q", expected, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestStatLowestGetCompressFactor(t *testing.T) {
|
||||
t.Run("adds missing IDs with value 1", func(t *testing.T) {
|
||||
s := &StatLowest{
|
||||
Events: map[string]float64{
|
||||
"id1": 10.0,
|
||||
"id2": 20.0,
|
||||
},
|
||||
}
|
||||
events := map[string]int{
|
||||
"id2": 5,
|
||||
}
|
||||
|
||||
got := s.GetCompressFactor(events)
|
||||
|
||||
expected := map[string]int{
|
||||
"id1": 1,
|
||||
"id2": 5,
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, expected) {
|
||||
t.Errorf("expected %v, got %v", expected, got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("no changes when all IDs exist", func(t *testing.T) {
|
||||
s := &StatLowest{
|
||||
Events: map[string]float64{
|
||||
"id1": 10.0,
|
||||
},
|
||||
}
|
||||
events := map[string]int{
|
||||
"id1": 2,
|
||||
}
|
||||
|
||||
got := s.GetCompressFactor(events)
|
||||
expected := map[string]int{"id1": 2}
|
||||
|
||||
if !reflect.DeepEqual(got, expected) {
|
||||
t.Errorf("expected %v, got %v", expected, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user