From d03e62c5a7025a6b439f6b3b62c5a288f61efd30 Mon Sep 17 00:00:00 2001 From: arberkatellari Date: Mon, 5 May 2025 17:04:10 +0200 Subject: [PATCH] Add tests for Session Update TotalUsage --- sessions/sessions_total_usage_it_test.go | 766 +++++++++++++++++++++++ 1 file changed, 766 insertions(+) create mode 100644 sessions/sessions_total_usage_it_test.go diff --git a/sessions/sessions_total_usage_it_test.go b/sessions/sessions_total_usage_it_test.go new file mode 100644 index 000000000..e0afac9df --- /dev/null +++ b/sessions/sessions_total_usage_it_test.go @@ -0,0 +1,766 @@ +//go:build integration +// +build integration + +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ +package sessions + +import ( + "path" + "testing" + "time" + + "github.com/cgrates/birpc" + "github.com/cgrates/birpc/context" + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +var ( + tUsageCfgPath string + tUsageCfgDIR string + tUsageCfg *config.CGRConfig + tUsageRPC *birpc.Client + + sessionsTUsageTests = []func(t *testing.T){ + testSessionsTUsageInitCfg, + testSessionsTUsageResetDataDb, + testSessionsTUsageResetStorDb, + testSessionsTUsageStartEngine, + testSessionsTUsageApierRpcConn, + testSessionsTUsageTPFromFolder, + testSessionsTUsageHigherThanSessionTUsage, + testSessionsTUsageTPFromFolder, + testSessionsTUsageLowerThanSessionTUsage, + testSessionsTUsageTPFromFolder, + testSessionsTUsageSameWithSessionTUsage, + testSessionsTUsageStopCgrEngine, + } +) + +func TestSessionsTUsage(t *testing.T) { + switch *utils.DBType { + case utils.MetaInternal: + tUsageCfgDIR = "sessions_internal" + case utils.MetaMySQL: + tUsageCfgDIR = "sessions_mysql" + case utils.MetaMongo: + tUsageCfgDIR = "sessions_mongo" + case utils.MetaPostgres: + t.SkipNow() + default: + t.Fatal("Unknown Database type") + } + for _, stest := range sessionsTUsageTests { + t.Run(tUsageCfgDIR, stest) + } +} + +func testSessionsTUsageInitCfg(t *testing.T) { + tUsageCfgPath = path.Join(*utils.DataDir, "conf", "samples", tUsageCfgDIR) + // Init config first + var err error + tUsageCfg, err = config.NewCGRConfigFromPath(tUsageCfgPath) + if err != nil { + t.Error(err) + } +} + +// Remove data in both rating and accounting db +func testSessionsTUsageResetDataDb(t *testing.T) { + if err := engine.InitDataDb(tUsageCfg); err != nil { + t.Fatal(err) + } +} + +// Wipe out the cdr database +func testSessionsTUsageResetStorDb(t *testing.T) { + if err := engine.InitStorDb(tUsageCfg); err != nil { + t.Fatal(err) + } +} + +// Start CGR Engine +func testSessionsTUsageStartEngine(t *testing.T) { + if _, err := engine.StopStartEngine(tUsageCfgPath, *utils.WaitRater); err != nil { + t.Fatal(err) + } +} + +// Connect rpc client to rater +func testSessionsTUsageApierRpcConn(t *testing.T) { + var err error + tUsageRPC, err = newRPCClient(tUsageCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} + +// Load the tariff plan, creating accounts and their balances +func testSessionsTUsageTPFromFolder(t *testing.T) { + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*utils.DataDir, "tariffplans", "oldtutorial")} + var loadInst utils.LoadInstance + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2LoadTariffPlanFromFolder, attrs, &loadInst); err != nil { + t.Error(err) + } + time.Sleep(time.Duration(*utils.WaitRater) * time.Millisecond) // Give time for scheduler to execute topups +} + +func testSessionsTUsageHigherThanSessionTUsage(t *testing.T) { + var acnt *engine.Account + attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} + eAcntVal := 10.0 + eAcntVoiceVal := float64(210 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + usage := 5 * time.Second + initArgs := &V1InitSessionArgs{ + InitSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsTUsageMonetaryRefund", + Event: map[string]any{ + utils.EventName: "TEST_EVENT", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: usage, + }, + }, + } + + var initRpl *V1InitSessionReply + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1InitiateSession, + initArgs, &initRpl); err != nil { + t.Error(err) + } + if initRpl.MaxUsage == nil || *initRpl.MaxUsage != usage { + t.Errorf("Expecting : %+v, received: %+v", usage, initRpl.MaxUsage) + } + + eAcntVoiceVal = float64(205 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + lastUsage := 5 * time.Second + updateArgs := &V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsVoiceLastUsed", + Event: map[string]any{ + utils.EventName: "Update1", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.Usage: usage, + utils.LastUsed: lastUsage, + }, + }, + } + + var updateRpl *V1UpdateSessionReply + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1UpdateSession, updateArgs, &updateRpl); err != nil { + t.Error(err) + } + if updateRpl.MaxUsage == nil || *updateRpl.MaxUsage != usage { + t.Errorf("Expected: %+v, received: %+v", usage, updateRpl.MaxUsage) + } + + eAcntVoiceVal = float64(200 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + lastUsage = 5 * time.Second + updateArgs = &V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsVoiceLastUsed", + Event: map[string]any{ + utils.EventName: "Update2", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: usage, + utils.LastUsed: lastUsage, + }, + }, + } + + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1UpdateSession, updateArgs, &updateRpl); err != nil { + t.Error(err) + } + if updateRpl.MaxUsage == nil || *updateRpl.MaxUsage != usage { + t.Errorf("Expected: %+v, received: %+v", usage, updateRpl.MaxUsage) + } + + eAcntVoiceVal = float64(195 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + ignoredUsage := 435 * time.Second + totalUsage := 105 * time.Second + lastUsage = 5 * time.Second + updateArgs = &V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsVoiceLastUsed", + Event: map[string]any{ + utils.EventName: "Update2", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: ignoredUsage, + utils.LastUsed: lastUsage, + utils.TotalUsage: totalUsage, + }, + }, + } + + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1UpdateSession, updateArgs, &updateRpl); err != nil { + t.Error(err) + } + if updateRpl.MaxUsage == nil || *updateRpl.MaxUsage != totalUsage-15*time.Second { // used 15 seconds up until this update. to get the max usage of this specific update it does totalUsage-15*time.Second + t.Errorf("Expected: %+v, received: %+v", totalUsage-15*time.Second, updateRpl.MaxUsage) + } + + eAcntVoiceVal = float64(210*time.Second) - float64(totalUsage) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + usage = 110 * time.Second + termArgs := &V1TerminateSessionArgs{ + TerminateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsTUsageVoiceRefund", + Event: map[string]any{ + utils.EventName: "TEST_EVENT", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: usage, + }, + }, + } + + var rpl string + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1TerminateSession, termArgs, &rpl); err != nil || rpl != utils.OK { + t.Error(err) + } + + eAcntVoiceVal = float64(210*time.Second) - float64(110*time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } +} + +func testSessionsTUsageLowerThanSessionTUsage(t *testing.T) { + var acnt *engine.Account + attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} + eAcntVal := 15.0 + eAcntVoiceVal := float64(210 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + usage := 5 * time.Second + initArgs := &V1InitSessionArgs{ + InitSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsTUsageMonetaryRefund", + Event: map[string]any{ + utils.EventName: "TEST_EVENT", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: usage, + }, + }, + } + + var initRpl *V1InitSessionReply + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1InitiateSession, + initArgs, &initRpl); err != nil { + t.Error(err) + } + if initRpl.MaxUsage == nil || *initRpl.MaxUsage != usage { + t.Errorf("Expecting : %+v, received: %+v", usage, initRpl.MaxUsage) + } + + eAcntVoiceVal = float64(205 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + lastUsage := 5 * time.Second + updateArgs := &V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsVoiceLastUsed", + Event: map[string]any{ + utils.EventName: "Update1", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.Usage: usage, + utils.LastUsed: lastUsage, + }, + }, + } + + var updateRpl *V1UpdateSessionReply + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1UpdateSession, updateArgs, &updateRpl); err != nil { + t.Error(err) + } + if updateRpl.MaxUsage == nil || *updateRpl.MaxUsage != usage { + t.Errorf("Expected: %+v, received: %+v", usage, updateRpl.MaxUsage) + } + + eAcntVoiceVal = float64(200 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + lastUsage = 5 * time.Second + updateArgs = &V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsVoiceLastUsed", + Event: map[string]any{ + utils.EventName: "Update2", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: usage, + utils.LastUsed: lastUsage, + }, + }, + } + + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1UpdateSession, updateArgs, &updateRpl); err != nil { + t.Error(err) + } + if updateRpl.MaxUsage == nil || *updateRpl.MaxUsage != usage { + t.Errorf("Expected: %+v, received: %+v", usage, updateRpl.MaxUsage) + } + + eAcntVoiceVal = float64(195 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + ignoredUsage := 435 * time.Second + totalUsage := 5 * time.Second + lastUsage = 5 * time.Second + updateArgs = &V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsVoiceLastUsed", + Event: map[string]any{ + utils.EventName: "Update2", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: ignoredUsage, + utils.LastUsed: lastUsage, + utils.TotalUsage: totalUsage, + }, + }, + } + + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1UpdateSession, updateArgs, &updateRpl); err != nil { + t.Error(err) + } + if updateRpl.MaxUsage == nil || *updateRpl.MaxUsage != 0 { // event total usage 5 is smaller than session total usage 15, return 0 max usage + t.Errorf("Expected: %+v, received: %+v", 0, updateRpl.MaxUsage) + } + + eAcntVoiceVal = float64(210*time.Second) - float64(25*time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + usage = 110 * time.Second + termArgs := &V1TerminateSessionArgs{ + TerminateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsTUsageVoiceRefund", + Event: map[string]any{ + utils.EventName: "TEST_EVENT", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: usage, + }, + }, + } + + var rpl string + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1TerminateSession, termArgs, &rpl); err != nil || rpl != utils.OK { + t.Error(err) + } + + eAcntVoiceVal = float64(210*time.Second) - float64(110*time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } +} + +func testSessionsTUsageSameWithSessionTUsage(t *testing.T) { + var acnt *engine.Account + attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} + eAcntVal := 20.0 + eAcntVoiceVal := float64(210 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + usage := 5 * time.Second + initArgs := &V1InitSessionArgs{ + InitSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsTUsageMonetaryRefund", + Event: map[string]any{ + utils.EventName: "TEST_EVENT", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: usage, + }, + }, + } + + var initRpl *V1InitSessionReply + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1InitiateSession, + initArgs, &initRpl); err != nil { + t.Error(err) + } + if initRpl.MaxUsage == nil || *initRpl.MaxUsage != usage { + t.Errorf("Expecting : %+v, received: %+v", usage, initRpl.MaxUsage) + } + + eAcntVoiceVal = float64(205 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + lastUsage := 5 * time.Second + updateArgs := &V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsVoiceLastUsed", + Event: map[string]any{ + utils.EventName: "Update1", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.Usage: usage, + utils.LastUsed: lastUsage, + }, + }, + } + + var updateRpl *V1UpdateSessionReply + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1UpdateSession, updateArgs, &updateRpl); err != nil { + t.Error(err) + } + if updateRpl.MaxUsage == nil || *updateRpl.MaxUsage != usage { + t.Errorf("Expected: %+v, received: %+v", usage, updateRpl.MaxUsage) + } + + eAcntVoiceVal = float64(200 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + lastUsage = 5 * time.Second + updateArgs = &V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsVoiceLastUsed", + Event: map[string]any{ + utils.EventName: "Update2", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: usage, + utils.LastUsed: lastUsage, + }, + }, + } + + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1UpdateSession, updateArgs, &updateRpl); err != nil { + t.Error(err) + } + if updateRpl.MaxUsage == nil || *updateRpl.MaxUsage != usage { + t.Errorf("Expected: %+v, received: %+v", usage, updateRpl.MaxUsage) + } + + eAcntVoiceVal = float64(195 * time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + + ignoredUsage := 435 * time.Second + totalUsage := 15 * time.Second + lastUsage = 5 * time.Second + updateArgs = &V1UpdateSessionArgs{ + UpdateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsVoiceLastUsed", + Event: map[string]any{ + utils.EventName: "Update2", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: ignoredUsage, + utils.LastUsed: lastUsage, + utils.TotalUsage: totalUsage, + }, + }, + } + + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1UpdateSession, updateArgs, &updateRpl); err != nil { + t.Error(err) + } + if updateRpl.MaxUsage == nil || *updateRpl.MaxUsage != 0 { // event total usage 15 is the same with the sessions total usage 15, return 0 max usage + t.Errorf("Expected: %+v, received: %+v", 0, updateRpl.MaxUsage) + } + + eAcntVoiceVal = float64(210*time.Second) - float64(15*time.Second) // no debiting was done + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } + usage = 110 * time.Second + termArgs := &V1TerminateSessionArgs{ + TerminateSession: true, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSessionsTUsageVoiceRefund", + Event: map[string]any{ + utils.EventName: "TEST_EVENT", + utils.ToR: utils.MetaVoice, + utils.OriginID: "12350", + utils.AccountField: "1001", + utils.Subject: "1001", + utils.Destination: "1003", + utils.Category: "call", + utils.Tenant: "cgrates.org", + utils.RequestType: utils.MetaPrepaid, + utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 49, 0, time.UTC), + utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC), + utils.Usage: usage, + }, + }, + } + + var rpl string + if err := tUsageRPC.Call(context.Background(), utils.SessionSv1TerminateSession, termArgs, &rpl); err != nil || rpl != utils.OK { + t.Error(err) + } + + eAcntVoiceVal = float64(210*time.Second) - float64(110*time.Second) + if err := tUsageRPC.Call(context.Background(), utils.APIerSv2GetAccount, attrs, &acnt); err != nil { + t.Error(err) + } else if acnt.BalanceMap[utils.MetaVoice].GetTotalValue() != eAcntVoiceVal { + t.Errorf("Expected: %f, received: %f", eAcntVoiceVal, acnt.BalanceMap[utils.MetaVoice].GetTotalValue()) + } else if acnt.BalanceMap[utils.MetaMonetary].GetTotalValue() != eAcntVal { + t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MetaMonetary].GetTotalValue()) + } +} + +func testSessionsTUsageStopCgrEngine(t *testing.T) { + if err := engine.KillEngine(1000); err != nil { + t.Error(err) + } +}