From d3975b4d2f7ccc4a97ecb5fbf1e08805750888d1 Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Tue, 18 Jun 2024 16:34:26 +0300 Subject: [PATCH] Update ActionTrigger integration test scenario Instead of using 2 balances and maintaining them using *transfer_balance, use only 1 balance. --- general_tests/transfer_balance_it_test.go | 225 ++++++++++++---------- 1 file changed, 121 insertions(+), 104 deletions(-) diff --git a/general_tests/transfer_balance_it_test.go b/general_tests/transfer_balance_it_test.go index 3a1c7cb04..26dfd7f2d 100644 --- a/general_tests/transfer_balance_it_test.go +++ b/general_tests/transfer_balance_it_test.go @@ -21,6 +21,7 @@ along with this program. If not, see package general_tests import ( + "bytes" "fmt" "sort" "testing" @@ -306,7 +307,7 @@ ACT_TRANSFER,*transfer_balance,"{""DestinationAccountID"":""cgrates.org:ACC_DEST }) } -func TestATExportAndTransfer(t *testing.T) { +func TestATExportAndTopup(t *testing.T) { switch *utils.DBType { case utils.MetaInternal: case utils.MetaMySQL, utils.MetaMongo, utils.MetaPostgres: @@ -356,9 +357,30 @@ func TestATExportAndTransfer(t *testing.T) { { "id": "test_exporter", "type": "*virt", - "flags": ["*log"], + "attempts": 1, + "synchronous": true, + "fields":[ + {"tag": "Balance", "filters": ["*empty:~*uch.ExportCount:"], "path": "*uch.ExportCount", "type": "*sum", "value": "0;1", "blocker": true}, + {"tag": "Balance", "path": "*uch.ExportCount", "type": "*sum", "value": "~*uch.ExportCount;1"} + ] + }, + { + "id": "simple_exporter", + "type": "*virt", "attempts": 1, "synchronous": true + }, + { + "id": "metadata_exporter", + "type": "*virt", + "attempts": 1, + "synchronous": true, + "fields":[ + {"tag": "ExportedAccountInfo", "path": "*exp.ExportedAccountInfo", "type": "*variable", "value": "~*req"}, + {"tag": "ActionTriggerID", "path": "*exp.ActionTrigger", "type": "*constant", "value": "TRIGGER_USAGE_1GB"}, + {"tag": "ActionsID", "path": "*exp.ActionsID", "type": "*constant", "value": "ACT_USAGE_1GB"}, + {"tag": "ActionType", "path": "*exp.ActionType", "type": "*constant", "value": "*export"} + ] } ] } @@ -367,119 +389,114 @@ func TestATExportAndTransfer(t *testing.T) { tpFiles := map[string]string{ utils.AccountActionsCsv: `#Tenant,Account,ActionPlanId,ActionTriggersId,AllowNegative,Disabled -cgrates.org,1001,PACKAGE_1001,EMPTY_BALANCE_TRIGGER,,`, +cgrates.org,1001,PACKAGE_1001,TRIGGER_USAGE_1GB,,`, utils.ActionPlansCsv: `#Id,ActionsId,TimingId,Weight -PACKAGE_1001,ACT_TOPUP_INITIAL,*asap, -#PACKAGE_1001,ACT_TOPUP_BUFFER,*asap, -#PACKAGE_1001,ACT_TOPUP_TRANSFER,*monthly,`, +PACKAGE_1001,ACT_TOPUP_1TB,*asap,`, utils.ActionsCsv: `#ActionsId[0],Action[1],ExtraParameters[2],Filter[3],BalanceId[4],BalanceType[5],Categories[6],DestinationIds[7],RatingSubject[8],SharedGroup[9],ExpiryTime[10],TimingIds[11],Units[12],BalanceWeight[13],BalanceBlocker[14],BalanceDisabled[15],Weight[16] -ACT_TOPUP_INITIAL,*topup_reset,,,main,*data,,,,,*unlimited,,11000,10,,,20 -ACT_TOPUP_INITIAL,*transfer_balance,"{""DestinationAccountID"":""cgrates.org:1001"",""DestinationBalanceID"":""buffer"",""DestinationReferenceValue"":10000}",,main,,,,,,,,,,,,10 -ACT_TOPUP_INITIAL,*cdrlog,"{""ToR"":""*data""}",,,,,,,,,,,,,,0 -ACT_EXPORT,*export,test_exporter,,,,,,,,,,,,,, -ACT_TOPUP_TRANSFER,*topup,,,main,*data,,,,,,,5000,,,,30 -ACT_TOPUP_TRANSFER,*transfer_balance,"{""DestinationAccountID"":""cgrates.org:1001"",""DestinationBalanceID"":""buffer"",""DestinationReferenceValue"":10000}",,main,,,,,,,,,,,,20 -ACT_TOPUP_TRANSFER,*cdrlog,"{""ToR"":""*data""}",,,,,,,,,,,,,,10 -ACT_TOPUP_TRANSFER,*reset_triggers,,,,,,,,,,,,,,,0`, +ACT_TOPUP_1TB,*topup_reset,,,main,*data,,,,,*unlimited,,1048576,,,, +ACT_USAGE_1GB,*export,test_exporter;simple_exporter;metadata_exporter,,,,,,,,,,,,,,30 +ACT_USAGE_1GB,*topup,,,main,*data,,,,,,,1024,,,,20 +ACT_USAGE_1GB,*cdrlog,"{""ToR"":""*data""}",,,,,,,,,,,,,,10 +ACT_USAGE_1GB,*reset_triggers,,,,,,,,,,,,,,,0`, utils.ActionTriggersCsv: `#Tag[0],UniqueId[1],ThresholdType[2],ThresholdValue[3],Recurrent[4],MinSleep[5],ExpiryTime[6],ActivationTime[7],BalanceTag[8],BalanceType[9],BalanceCategories[10],BalanceDestinationIds[11],BalanceRatingSubject[12],BalanceSharedGroup[13],BalanceExpiryTime[14],BalanceTimingIds[15],BalanceWeight[16],BalanceBlocker[17],BalanceDisabled[18],ActionsId[19],Weight[20] -EMPTY_BALANCE_TRIGGER,,*min_balance,9999,false,0,,,buffer,*data,,,,,,,,,,ACT_EXPORT, -#EMPTY_BALANCE_TRIGGER,,*min_balance,0,false,0,,,buffer,*data,,,,,,,,,,ACT_EXPORT,`, +TRIGGER_USAGE_1GB,,*min_balance,1047552,false,0,,,main,*data,,,,,,,,,,ACT_USAGE_1GB,`, } testEnv := TestEnvironment{ ConfigJSON: content, TpFiles: tpFiles, - // LogBuffer: &bytes.Buffer{}, + LogBuffer: &bytes.Buffer{}, } // defer fmt.Println(testEnv.LogBuffer) - client, _ := testEnv.Setup(t, 0) + client, _ := testEnv.Setup(t, 10) + + // helper functions + i := 0 + balanceID := "main" + + // processCDRs processes 'count' CDRs, each debiting 'amount'. + processCDRs := func(t *testing.T, count int, amount int) { + t.Helper() + var reply string + for range count { + i++ + if err := client.Call(context.Background(), utils.CDRsV1ProcessEvent, + &engine.ArgV1ProcessEvent{ + Flags: []string{utils.MetaRALs}, + CGREvent: utils.CGREvent{ + Tenant: "cgrates.org", + ID: fmt.Sprintf("event%d", i), + Event: map[string]any{ + utils.ToR: utils.MetaData, + utils.OriginID: fmt.Sprintf("processCDR%d", i), + utils.RequestType: utils.MetaPostpaid, + utils.AccountField: "1001", + utils.Usage: amount, + }, + }, + }, &reply); err != nil { + t.Errorf("CDRsV1ProcessEvent(%d) failed unexpectedly: %v", i, err) + } + } + } + + checkAccountAndCDRs := func(t *testing.T, wantBalVal float64, triggerCount int) { + t.Helper() + var acnts []*engine.Account + if err := client.Call(context.Background(), utils.APIerSv2GetAccounts, + &utils.AttrGetAccounts{ + Tenant: "cgrates.org", + }, &acnts); err != nil { + t.Errorf("APIerSv2GetAccounts failed unexpectedly: %v", err) + } + if len(acnts) != 1 { + t.Fatalf("APIerSv2GetAccounts len(acnts)=%v, want 1", len(acnts)) + } + got, _ := acnts[0].FindBalanceByID(balanceID) + if got == nil { + t.Errorf("acnts[0].FindBalanceByID(%q) could not find balance", balanceID) + } else if got.Value != wantBalVal { + t.Errorf("acnts[0].FindBalanceByID(%q) returned balance with value %v, want %v", balanceID, got.Value, wantBalVal) + } + var cdrs []*engine.CDR + if err := client.Call(context.Background(), utils.CDRsV1GetCDRs, &utils.RPCCDRsFilterWithAPIOpts{ + RPCCDRsFilter: &utils.RPCCDRsFilter{ + RunIDs: []string{utils.MetaTopUp}, + }}, &cdrs); err != nil && triggerCount != 0 { + t.Errorf("CDRsV1GetCDRs failed unexpectedly: %v", err) + } else if noCDRs := len(cdrs); noCDRs != triggerCount { + t.Errorf("CDRsV1GetCDRs *topup cdrs count=%d, want %d", noCDRs, triggerCount) + } + + var count any + if err = client.Call(context.Background(), utils.CacheSv1GetItem, &utils.ArgsGetCacheItemWithAPIOpts{ + Tenant: "cgrates.org", + ArgsGetCacheItem: utils.ArgsGetCacheItem{ + CacheID: utils.CacheUCH, + ItemID: "ExportCount", + }, + }, &count); err != nil && triggerCount != 0 { + t.Errorf("CacheSv1GetItem failed unexpectedly: %v", err) + } else { + if count == nil { + count = 0.0 + } + if count != float64(triggerCount) { + t.Errorf("CacheSv1GetItem *uch.ExportCount=%v, want %v", count, triggerCount) + } + } + } t.Run("ProcessCDRs", func(t *testing.T) { - i := 0 - processCDRs := func(t *testing.T, count int, amount int) { - // fmt.Println("===========ProcessCDRs===========") - t.Helper() - var reply string - for range count { - i++ - if err := client.Call(context.Background(), utils.CDRsV1ProcessEvent, - &engine.ArgV1ProcessEvent{ - Flags: []string{utils.MetaRALs}, - CGREvent: utils.CGREvent{ - Tenant: "cgrates.org", - ID: fmt.Sprintf("event%d", i), - Event: map[string]any{ - utils.RunID: "*default", - utils.Tenant: "cgrates.org", - utils.Category: "data", - utils.ToR: utils.MetaData, - utils.OriginID: fmt.Sprintf("processCDR%d", i), - utils.OriginHost: "127.0.0.1", - utils.RequestType: utils.MetaPostpaid, - utils.AccountField: "1001", - utils.Destination: "1002", - utils.SetupTime: time.Date(2021, time.February, 2, 16, 14, 50, 0, time.UTC), - utils.AnswerTime: time.Date(2021, time.February, 2, 16, 15, 0, 0, time.UTC), - utils.Usage: amount, - }, - }, - }, &reply); err != nil { - t.Errorf("CDRsV1ProcessEvent(%d) err: %v", i, err) - } - } - } - - checkAccountAndCDRs := func(t *testing.T) { - // fmt.Println("===========CheckAcc===========") - t.Helper() - var acnts []*engine.Account - err := client.Call(context.Background(), utils.APIerSv2GetAccounts, - &utils.AttrGetAccounts{ - Tenant: "cgrates.org", - }, &acnts) - t.Logf("APIerSv2GetAccounts err: %v", err) - var cdrs []*engine.CDR - err = client.Call(context.Background(), utils.CDRsV1GetCDRs, &utils.RPCCDRsFilterWithAPIOpts{ - RPCCDRsFilter: &utils.RPCCDRsFilter{ - RunIDs: []string{utils.MetaTopUp, utils.MetaTransferBalance}, - }}, &cdrs) - t.Logf("CDRsV1GetCDRs err: %v", err) - - // fmt.Println(utils.ToJSON(acnts[0].BalanceMap["*data"])) - // fmt.Println(utils.ToJSON(cdrs)) - } - - executeAction := func(t *testing.T, id string) { - var reply string - attrsEA := &utils.AttrExecuteAction{Tenant: "cgrates.org", Account: "1001", ActionsId: id} - if err := client.Call(context.Background(), utils.APIerSv1ExecuteAction, attrsEA, &reply); err != nil { - t.Errorf("APIerSv1ExecuteAction err: %v", err) - } - } - - time.Sleep(100 * time.Millisecond) - checkAccountAndCDRs(t) // main 1000 buffer 10000 total 11000 - processCDRs(t, 2, 600) // -1200 + export - checkAccountAndCDRs(t) // main 0 buffer 9800 total 9800 - executeAction(t, "ACT_TOPUP_TRANSFER") // +5000 - checkAccountAndCDRs(t) // main 4800 buffer 10000 total 14800 - processCDRs(t, 8, 600) // -4800 (no export) - checkAccountAndCDRs(t) // main 0 buffer 10000 total 10000 - processCDRs(t, 1, 600) // -600 + export - checkAccountAndCDRs(t) // main 0 buffer 9400 total 9400 - - var reply string - if err := client.Call(context.Background(), utils.APIerSv1TransferBalance, utils.AttrTransferBalance{ - Tenant: "cgrates.org", - SourceAccountID: "1001", - SourceBalanceID: "main", - DestinationAccountID: "1001", - DestinationBalanceID: "buffer", - DestinationReferenceValue: utils.Float64Pointer(5000), - Cdrlog: true, - }, &reply); err != nil { - t.Error(err) - } - checkAccountAndCDRs(t) // main 4400 buffer 5000 total 9400 + time.Sleep(10 * time.Millisecond) + checkAccountAndCDRs(t, 1048576, 0) // 1TB balance + processCDRs(t, 1, 512) // -0.5GB debit, triggered 0 times + checkAccountAndCDRs(t, 1048064, 0) // 1TB-0.5GB balance + processCDRs(t, 1, 1024) // -1GB debit, triggered 1 time + checkAccountAndCDRs(t, 1048064, 1) // 1TB-0.5GB balance + processCDRs(t, 1, 2816) // -2.75GB debit, triggered 3 times + checkAccountAndCDRs(t, 1048320, 4) // 1TB-0.25GB balance + processCDRs(t, 1, 512) // -0.5GB debit, triggered 0 times + checkAccountAndCDRs(t, 1047808, 4) // 1TB-0.75GB balance }) }