From 968c9ebb31ab51621d8e93311fb95d7e2fd67b90 Mon Sep 17 00:00:00 2001 From: armirveliaj Date: Thu, 25 Jul 2024 09:37:40 -0400 Subject: [PATCH] Add new unit tests on migrator --- migrator/accounts_test.go | 65 +++++++++++++++++ migrator/filters_test.go | 47 ++++++++++++ migrator/thresholds_test.go | 138 ++++++++++++++++++++++++++++++++++++ 3 files changed, 250 insertions(+) diff --git a/migrator/accounts_test.go b/migrator/accounts_test.go index e7229dfbe..b62de3bca 100644 --- a/migrator/accounts_test.go +++ b/migrator/accounts_test.go @@ -121,3 +121,68 @@ func TestV1AccountAsAccount(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v", testAccount.BalanceMap["*data"][0], newAcc.BalanceMap["*data"][0]) } } +func TestV2toV3Account(t *testing.T) { + v2Acc := &v2Account{ + ID: "account1", + BalanceMap: map[string]engine.Balances{ + "balance1": { + {}, + }, + }, + UnitCounters: engine.UnitCounters{ + "counter1": { + &engine.UnitCounter{ + Counters: []*engine.CounterFilter{ + { + Value: 100.0, + Filter: &engine.BalanceFilter{}, + }, + }, + }, + }, + }, + ActionTriggers: engine.ActionTriggers{}, + AllowNegative: false, + Disabled: false, + } + v3Acc := v2Acc.V2toV3Account() + if v3Acc.ID != v2Acc.ID { + t.Errorf("expected ID %s, got %s", v2Acc.ID, v3Acc.ID) + } + for key, v2Balances := range v2Acc.BalanceMap { + v3Balances, exists := v3Acc.BalanceMap[key] + if !exists { + t.Errorf("balance map key %s not found in v3 account", key) + continue + } + if len(v3Balances) != len(v2Balances) { + t.Errorf("expected %d balances for key %s, got %d", len(v2Balances), key, len(v3Balances)) + continue + } + for i, v2Bal := range v2Balances { + v3Bal := v3Balances[i] + if v3Bal.ID != v2Bal.ID || v3Bal.Value != v2Bal.Value { + t.Errorf("expected balance %+v, got %+v", v2Bal, v3Bal) + } + } + } + + for key, v2UnitCounters := range v2Acc.UnitCounters { + v3UnitCounters, exists := v3Acc.UnitCounters[key] + if !exists { + t.Errorf("unit counters key %s not found in v3 account", key) + continue + } + if len(v3UnitCounters) != len(v2UnitCounters) { + t.Errorf("expected %d unit counters for key %s, got %d", len(v2UnitCounters), key, len(v3UnitCounters)) + continue + } + for i, v2Uc := range v2UnitCounters { + v3Uc := v3UnitCounters[i] + if len(v3Uc.Counters) != len(v2Uc.Counters) { + t.Errorf("expected %d counters for unit counter %d, got %d", len(v2Uc.Counters), i, len(v3Uc.Counters)) + } + } + } + +} diff --git a/migrator/filters_test.go b/migrator/filters_test.go index 4d97ad6ed..a4bee9ec3 100644 --- a/migrator/filters_test.go +++ b/migrator/filters_test.go @@ -21,6 +21,7 @@ package migrator import ( "reflect" "testing" + "time" "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" @@ -281,3 +282,49 @@ func TestFiltersInlineV2Migrate(t *testing.T) { } } + +func TestMigrateFilterV3(t *testing.T) { + v1F := &v1Filter{ + Tenant: "cgrates.org", + ID: "filter1", + Rules: []*v1FilterRule{ + {Type: "type1", FieldName: "field1", Values: []string{"value1", "value2"}}, + {Type: "type2", FieldName: "field2", Values: []string{"value3"}}, + }, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Now(), + ExpiryTime: time.Now().Add(24 * time.Hour), + }, + } + fltr := migrateFilterV3(v1F) + if fltr.Tenant != v1F.Tenant { + t.Errorf("expected Tenant %v, got %v", v1F.Tenant, fltr.Tenant) + } + if fltr.ID != v1F.ID { + t.Errorf("expected ID %v, got %v", v1F.ID, fltr.ID) + } + if len(fltr.Rules) != len(v1F.Rules) { + t.Errorf("expected %v rules, got %v", len(v1F.Rules), len(fltr.Rules)) + } else { + for i, rule := range v1F.Rules { + if fltr.Rules[i].Type != rule.Type { + t.Errorf("for rule %d, expected Type %v, got %v", i, rule.Type, fltr.Rules[i].Type) + } + if fltr.Rules[i].Element != rule.FieldName { + t.Errorf("for rule %d, expected FieldName %v, got %v", i, rule.FieldName, fltr.Rules[i].Element) + } + if len(fltr.Rules[i].Values) != len(rule.Values) { + t.Errorf("for rule %d, expected %v values, got %v", i, len(rule.Values), len(fltr.Rules[i].Values)) + } else { + for j, value := range rule.Values { + if fltr.Rules[i].Values[j] != value { + t.Errorf("for rule %d, expected value %v, got %v", i, value, fltr.Rules[i].Values[j]) + } + } + } + } + } + if fltr.ActivationInterval != nil && (fltr.ActivationInterval.ActivationTime != v1F.ActivationInterval.ActivationTime || fltr.ActivationInterval.ExpiryTime != v1F.ActivationInterval.ExpiryTime) { + t.Errorf("expected ActivationInterval %+v, got %+v", v1F.ActivationInterval, fltr.ActivationInterval) + } +} diff --git a/migrator/thresholds_test.go b/migrator/thresholds_test.go index 17929ddf8..882d2470a 100644 --- a/migrator/thresholds_test.go +++ b/migrator/thresholds_test.go @@ -18,6 +18,7 @@ along with this program. If not, see package migrator import ( + "encoding/json" "reflect" "testing" "time" @@ -99,3 +100,140 @@ func TestV2ActionTriggerAsThreshold(t *testing.T) { t.Errorf("expected: %+v,\nreceived: %+v", filter, fltr) } } + +func TestV2toV3Threshold(t *testing.T) { + activationInterval := &utils.ActivationInterval{} + v2ThresholdInstance := v2Threshold{ + Tenant: "cgrates.org", + ID: "id1", + FilterIDs: []string{"filter1", "filter2"}, + ActivationInterval: activationInterval, + Recurrent: true, + MinHits: 10, + MinSleep: 5 * time.Minute, + Blocker: true, + Weight: 1.5, + ActionIDs: []string{"action1", "action2"}, + Async: false, + } + expectedThresholdProfile := &engine.ThresholdProfile{ + Tenant: "cgrates.org", + ID: "id1", + FilterIDs: []string{"filter1", "filter2"}, + ActivationInterval: activationInterval, + MinHits: 10, + MinSleep: 5 * time.Minute, + Blocker: true, + Weight: 1.5, + ActionIDs: []string{"action1", "action2"}, + Async: false, + MaxHits: -1, + } + result := v2ThresholdInstance.V2toV3Threshold() + + if !reflect.DeepEqual(result, expectedThresholdProfile) { + t.Errorf("V2toV3Threshold() = %v, want %v", result, expectedThresholdProfile) + } + v2ThresholdInstance.Recurrent = false + expectedThresholdProfile.MaxHits = 1 + result = v2ThresholdInstance.V2toV3Threshold() + if !reflect.DeepEqual(result, expectedThresholdProfile) { + t.Errorf("V2toV3Threshold() = %v, want %v", result, expectedThresholdProfile) + } +} + +func TestAsSessionsCostSql(t *testing.T) { + v2Cost := &v2SessionsCost{ + CGRID: "cgrid1", + RunID: "runid1", + OriginHost: "originhost1", + OriginID: "originid1", + CostSource: "costsource1", + CostDetails: nil, + Usage: 5 * time.Second, + } + + smSql := v2Cost.AsSessionsCostSql() + if smSql.Cgrid != v2Cost.CGRID { + t.Errorf("expected Cgrid %v, got %v", v2Cost.CGRID, smSql.Cgrid) + } + + if smSql.RunID != v2Cost.RunID { + t.Errorf("expected RunID %v, got %v", v2Cost.RunID, smSql.RunID) + } + + if smSql.OriginHost != v2Cost.OriginHost { + t.Errorf("expected OriginHost %v, got %v", v2Cost.OriginHost, smSql.OriginHost) + } + + if smSql.OriginID != v2Cost.OriginID { + t.Errorf("expected OriginID %v, got %v", v2Cost.OriginID, smSql.OriginID) + } + + if smSql.CostSource != v2Cost.CostSource { + t.Errorf("expected CostSource %v, got %v", v2Cost.CostSource, smSql.CostSource) + } + + expectedCostDetails := utils.ToJSON(v2Cost.CostDetails) + if smSql.CostDetails != expectedCostDetails { + t.Errorf("expected CostDetails %v, got %v", expectedCostDetails, smSql.CostDetails) + } + + expectedUsage := v2Cost.Usage.Nanoseconds() + if smSql.Usage != expectedUsage { + t.Errorf("expected Usage %v, got %v", expectedUsage, smSql.Usage) + } + + if smSql.CreatedAt.IsZero() { + t.Error("expected CreatedAt to be set, got zero value") + } +} + +func TestNewV2SessionsCostFromSessionsCostSql(t *testing.T) { + smSql := &engine.SessionCostsSQL{ + Cgrid: "cgrid1", + RunID: "runid1", + OriginHost: "originhost1", + OriginID: "originid1", + CostSource: "costsource1", + CostDetails: `{"detail1": "value1", "detail2": "value2"}`, + Usage: 5 * time.Second.Nanoseconds(), + CreatedAt: time.Now(), + } + + smV2, err := NewV2SessionsCostFromSessionsCostSql(smSql) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + + if smV2.CGRID != smSql.Cgrid { + t.Errorf("expected CGRID %v, got %v", smSql.Cgrid, smV2.CGRID) + } + + if smV2.RunID != smSql.RunID { + t.Errorf("expected RunID %v, got %v", smSql.RunID, smV2.RunID) + } + + if smV2.OriginHost != smSql.OriginHost { + t.Errorf("expected OriginHost %v, got %v", smSql.OriginHost, smV2.OriginHost) + } + + if smV2.OriginID != smSql.OriginID { + t.Errorf("expected OriginID %v, got %v", smSql.OriginID, smV2.OriginID) + } + + if smV2.CostSource != smSql.CostSource { + t.Errorf("expected CostSource %v, got %v", smSql.CostSource, smV2.CostSource) + } + + expectedUsage := time.Duration(smSql.Usage) + if smV2.Usage != expectedUsage { + t.Errorf("expected Usage %v, got %v", expectedUsage, smV2.Usage) + } + + var expectedCostDetails map[string]interface{} + if err := json.Unmarshal([]byte(smSql.CostDetails), &expectedCostDetails); err != nil { + t.Fatalf("failed to unmarshal CostDetails: %v", err) + } + +}