From 9f0c6cd6bbfd539c53c9d37618c88e8d12581cd0 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 22 Mar 2019 12:48:14 +0200 Subject: [PATCH] Updated and added integration tests for *remove_session_costs action --- engine/action.go | 11 +- engine/actions2_it_test.go | 230 +++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 6 deletions(-) create mode 100644 engine/actions2_it_test.go diff --git a/engine/action.go b/engine/action.go index 8cd1f4dae..ed69ab31e 100644 --- a/engine/action.go +++ b/engine/action.go @@ -963,14 +963,13 @@ func (cdrP *cdrLogProvider) RemoteHost() net.Addr { return utils.LocalAddr() } -func removeSessionCosts(_ *Account, _ *Action, _ Actions, extraData interface{}) error { // FiltersID;inlineFilter - fltrs, err := utils.IfaceAsString(extraData) - if err != nil { - return err - } +func removeSessionCosts(_ *Account, action *Action, _ Actions, _ interface{}) error { // FiltersID;inlineFilter tenant := config.CgrConfig().GeneralCfg().DefaultTenant smcFilter := new(utils.SMCostFilter) - for _, fltrID := range strings.Split(fltrs, utils.INFIELD_SEP) { + for _, fltrID := range strings.Split(action.ExtraParameters, utils.INFIELD_SEP) { + if len(fltrID) == 0 { + continue + } fltr, err := dm.GetFilter(tenant, fltrID, true, true, utils.NonTransactional) if err != nil { utils.Logger.Warning(fmt.Sprintf("<%s> Error: %s for filter: %s in action: <%s>", diff --git a/engine/actions2_it_test.go b/engine/actions2_it_test.go new file mode 100644 index 000000000..142e0f020 --- /dev/null +++ b/engine/actions2_it_test.go @@ -0,0 +1,230 @@ +// +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 engine + +import ( + "net/rpc" + "net/rpc/jsonrpc" + "path" + "testing" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/utils" +) + +var ( + actsCdrStore CdrStorage + actsCfgPath string + actsCfgDir string + actsCfg *config.CGRConfig + actsRPC *rpc.Client +) + +var sTestsActions = []func(t *testing.T){ + testActionsInitCfg, + testActionsInitCdrsStore, + testActionsInitDataDb, + testActionsResetStorDb, + testActionsStartEngine, + testActionsRPCConn, + testActionsSetSMCosts, + testActionsExecuteRemoveSMCos1, + testActionsExecuteRemoveSMCos2, + testActionsKillEngine, +} + +func TestActionsITRemoveSMCostRedis(t *testing.T) { + actsCfgDir = "actions" + for _, stest := range sTestsActions { + t.Run("TestsActionsITRedis", stest) + } +} + +func TestActionsITRemoveSMCostMongo(t *testing.T) { + actsCfgDir = "cdrsv2mongo" + for _, stest := range sTestsActions { + t.Run("TestsActionsITMongo", stest) + } +} + +func testActionsInitCfg(t *testing.T) { + var err error + actsCfgPath = path.Join(*dataDir, "conf", "samples", actsCfgDir) + actsCfg, err = config.NewCGRConfigFromPath(actsCfgPath) + if err != nil { + t.Error(err) + } +} + +func testActionsInitCdrsStore(t *testing.T) { + if actsCfgDir == "actions" { + if actsCdrStore, err = NewMySQLStorage(actsCfg.StorDbCfg().StorDBHost, + actsCfg.StorDbCfg().StorDBPort, actsCfg.StorDbCfg().StorDBName, + actsCfg.StorDbCfg().StorDBUser, actsCfg.StorDbCfg().StorDBPass, + actsCfg.StorDbCfg().StorDBMaxOpenConns, actsCfg.StorDbCfg().StorDBMaxIdleConns, + actsCfg.StorDbCfg().StorDBConnMaxLifetime); err != nil { + t.Fatal("Could not connect to mysql", err.Error()) + } + + } else if actsCfgDir == "cdrsv2mongo" { + if actsCdrStore, err = NewMongoStorage(actsCfg.StorDbCfg().StorDBHost, + actsCfg.StorDbCfg().StorDBPort, actsCfg.StorDbCfg().StorDBName, + actsCfg.StorDbCfg().StorDBUser, actsCfg.StorDbCfg().StorDBPass, + utils.StorDB, nil, actsCfg.CacheCfg(), false); err != nil { + t.Fatal("Could not connect to mongo", err.Error()) + } + } +} + +func testActionsInitDataDb(t *testing.T) { + if err := InitDataDb(actsCfg); err != nil { + t.Fatal(err) + } +} + +// Wipe out the cdr database +func testActionsResetStorDb(t *testing.T) { + if err := InitStorDb(actsCfg); err != nil { + t.Fatal(err) + } +} + +// Start CGR Engine +func testActionsStartEngine(t *testing.T) { + if _, err := StopStartEngine(actsCfgPath, *waitRater); err != nil { + t.Fatal(err) + } +} + +// Connect rpc client to rater +func testActionsRPCConn(t *testing.T) { + var err error + actsRPC, err = jsonrpc.Dial("tcp", actsCfg.ListenCfg().RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} + +func testActionsSetSMCosts(t *testing.T) { + var snd = []*SMCost{ + { + CGRID: "CGRID11", + RunID: "21", + OriginHost: "host32", + OriginID: "11", + CostDetails: NewBareEventCost(), + }, + { + CGRID: "CGRID12", + RunID: "22", + OriginHost: "host32", + OriginID: "12", + CostDetails: NewBareEventCost(), + }, + { + CGRID: "CGRID13", + RunID: "23", + OriginHost: "host33", + OriginID: "13", + CostDetails: NewBareEventCost(), + }, + } + for _, smc := range snd { + if err := actsCdrStore.SetSMCost(smc); err != nil { + t.Error(err) + } + } + // READ + if rcv, err := actsCdrStore.GetSMCosts("", "", "", ""); err != nil { + t.Fatal(err) + } else if len(rcv) != 3 { + t.Errorf("Expected 3 results received %v ", len(rcv)) + } +} + +func testActionsExecuteRemoveSMCos1(t *testing.T) { + var reply string + attrsAA := &utils.AttrSetActions{ + ActionsId: "REMOVE_SMCOST1", + Actions: []*utils.TPAction{ + { + Identifier: MetaRemoveSessionCosts, + TimingTags: utils.ASAP, + ExtraParameters: "*string:~OriginID:13;*notstring:~OriginID:12", + Weight: 20, + }, + }, + } + if err := actsRPC.Call("ApierV2.SetActions", attrsAA, &reply); err != nil && err.Error() != utils.ErrExists.Error() { + t.Error("Got error on ApierV2.SetActions: ", err.Error()) + } else if reply != utils.OK { + t.Errorf("Calling ApierV2.SetActions received: %s", reply) + } + attrsEA := &utils.AttrExecuteAction{Tenant: "cgrates.org", ActionsId: attrsAA.ActionsId} + if err := actsRPC.Call("ApierV1.ExecuteAction", attrsEA, &reply); err != nil { + t.Error("Got error on ApierV1.ExecuteAction: ", err.Error()) + } else if reply != utils.OK { + t.Errorf("Calling ApierV1.ExecuteAction received: %s", reply) + } + + // READ + if rcv, err := actsCdrStore.GetSMCosts("", "", "", ""); err != nil { + t.Error(err) + } else if len(rcv) != 2 { + t.Errorf("Expected 2 result received %v ", len(rcv)) + } +} + +func testActionsExecuteRemoveSMCos2(t *testing.T) { + var reply string + attrsAA := &utils.AttrSetActions{ + ActionsId: "REMOVE_SMCOST2", + Actions: []*utils.TPAction{ + { + Identifier: MetaRemoveSessionCosts, + TimingTags: utils.ASAP, + ExtraParameters: "", + Weight: 20, + }, + }, + } + if err := actsRPC.Call("ApierV2.SetActions", attrsAA, &reply); err != nil && err.Error() != utils.ErrExists.Error() { + t.Error("Got error on ApierV2.SetActions: ", err.Error()) + } else if reply != utils.OK { + t.Errorf("Calling ApierV2.SetActions received: %s", reply) + } + attrsEA := &utils.AttrExecuteAction{Tenant: "cgrates.org", ActionsId: attrsAA.ActionsId} + if err := actsRPC.Call("ApierV1.ExecuteAction", attrsEA, &reply); err != nil { + t.Error("Got error on ApierV1.ExecuteAction: ", err.Error()) + } else if reply != utils.OK { + t.Errorf("Calling ApierV1.ExecuteAction received: %s", reply) + } + + // READ + if _, err := actsCdrStore.GetSMCosts("", "", "", ""); err != utils.ErrNotFound { + t.Error(err) + } +} + +func testActionsKillEngine(t *testing.T) { + if err := KillEngine(100); err != nil { + t.Error(err) + } +}