diff --git a/actions/accounts_test.go b/actions/accounts_test.go new file mode 100644 index 000000000..3d7e11a6b --- /dev/null +++ b/actions/accounts_test.go @@ -0,0 +1,137 @@ +/* +Real-time Online/Offline Charging System (OerS) 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 actions + +import ( + "testing" + "time" + + "github.com/cgrates/rpcclient" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +func TestACExecuteAccountsSetBalance(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + internalChan := make(chan rpcclient.ClientConnector, 1) + connMngr := engine.NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAccounts): internalChan, + }) + apAction := &engine.APAction{ + ID: "TestACExecuteAccounts", + Type: utils.MetaSetBalance, + Diktats: []*engine.APDiktat{ + { + Path: "~*balance.TestBalance.Value", + Value: "\"constant;`>;q=0.7;expires=3600constant\"", + }, + }, + } + + dataStorage := utils.MapStorage{ + utils.MetaReq: map[string]interface{}{ + utils.AccountField: "1001", + }, + utils.MetaOpts: map[string]interface{}{ + utils.Usage: 10 * time.Minute, + }, + } + + actCdrLG := &actSetBalance{ + config: cfg, + connMgr: connMngr, + aCfg: apAction, + } + + expected := "no connection with AccountS" + if err := actCdrLG.execute(nil, dataStorage, utils.MetaBalanceLimit); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } + + actCdrLG.config.ActionSCfg().AccountSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAccounts)} + expected = "Closed unspilit syntax " + if err := actCdrLG.execute(nil, dataStorage, utils.MetaBalanceLimit); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } + + //invalid to parse a value from diktats + actCdrLG.aCfg.Diktats[0].Value = "10" + expected = "DISCONNECTED" + if err := actCdrLG.execute(nil, dataStorage, utils.MetaBalanceLimit); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } +} + +func TestACExecuteAccountsRemBalance(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + internalChan := make(chan rpcclient.ClientConnector, 1) + connMngr := engine.NewConnManager(cfg, map[string]chan rpcclient.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAccounts): internalChan, + }) + apAction := &engine.APAction{ + ID: "TestACExecuteAccountsRemBalance", + Type: utils.MetaSetBalance, + Diktats: []*engine.APDiktat{ + { + Path: "~*balance.TestBalance.Value", + Value: "10", + }, + }, + } + + actRemBal := &actRemBalance{ + config: cfg, + connMgr: connMngr, + aCfg: apAction, + tnt: "cgrates.org", + } + + expected := "no connection with AccountS" + if err := actRemBal.execute(nil, nil, utils.MetaRemBalance); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } + + actRemBal.config.ActionSCfg().AccountSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAccounts)} + expected = "DISCONNECTED" + if err := actRemBal.execute(nil, nil, utils.MetaRemBalance); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } +} + +func TestACAccountsGetIDs(t *testing.T) { + apAction := &engine.APAction{ + ID: "TestACExecuteAccountsRemBalance", + } + + actRemBal := &actRemBalance{ + aCfg: apAction, + } + if rcv := actRemBal.id(); rcv != apAction.ID { + t.Errorf("Expected %+v, received %+v", apAction.ID, rcv) + } + + actSeTBal := &actSetBalance{ + aCfg: apAction, + } + if rcv := actSeTBal.id(); rcv != apAction.ID { + t.Errorf("Expected %+v, received %+v", apAction.ID, rcv) + } +} diff --git a/actions/export_test.go b/actions/export_test.go new file mode 100644 index 000000000..99c1cb003 --- /dev/null +++ b/actions/export_test.go @@ -0,0 +1,145 @@ +/* +Real-time Online/Offline Charging System (OerS) 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 actions + +import ( + "bytes" + "log" + "strings" + "testing" + "time" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +func TestACHTTPPostExecute(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + apAction := &engine.APAction{ + ID: "TEST_ACTION_HTTPPOST", + Type: utils.CDRLog, + Diktats: []*engine.APDiktat{ + { + Path: "~*balance.TestBalance.Value", + Value: "10", + }, + }, + } + http := &actHTTPPost{ + config: cfg, + aCfg: apAction, + } + + dataStorage := utils.MapStorage{ + utils.MetaReq: map[string]interface{}{ + utils.AccountField: "1001", + }, + utils.MetaOpts: map[string]interface{}{ + utils.Usage: 10 * time.Minute, + }, + } + + var err error + utils.Logger, err = utils.Newlogger(utils.MetaStdLog, utils.EmptyString) + if err != nil { + t.Error(err) + } + utils.Logger.SetLogLevel(7) + + buff := new(bytes.Buffer) + log.SetOutput(buff) + + expected := "[WARNING] Posting to : <~*balance.TestBalance.Value>, error: " + if err := http.execute(nil, dataStorage, utils.EmptyString); err != nil { + t.Error(err) + } else if rcv := buff.String(); !strings.Contains(rcv, expected) { + t.Errorf("Expected %+v, received %+v", expected, rcv) + } + + buff.Reset() + + // channels cannot be marshaled + dataStorage[utils.MetaReq] = make(chan struct{}, 1) + expected = "json: unsupported type: chan struct {}" + if err := http.execute(nil, dataStorage, utils.EmptyString); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } + + dataStorage = utils.MapStorage{ + utils.MetaOpts: map[string]interface{}{ + utils.MetaAsync: 10 * time.Minute, + }, + } + http.aCfg.Opts = make(map[string]interface{}) + http.aCfg.Opts[utils.MetaAsync] = true + http.config.GeneralCfg().FailedPostsDir = utils.MetaNone + if err := http.execute(nil, dataStorage, utils.EmptyString); err != nil { + t.Error(err) + } +} + +func TestACHTTPPostValues(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + cfg.GeneralCfg().FailedPostsDir = utils.MetaNone + apAction := &engine.APAction{ + ID: "TEST_ACTION_HTTPPostValues", + Type: utils.MetaHTTPPost, + Diktats: []*engine.APDiktat{ + { + Path: "~*balance.TestBalance.Value", + Value: "80", + }, + }, + } + http := &actHTTPPost{ + config: cfg, + aCfg: apAction, + } + dataStorage := utils.MapStorage{ + utils.MetaReq: map[string]interface{}{ + utils.AccountField: 1003, + }, + } + + if err := http.execute(nil, dataStorage, + utils.EmptyString); err == nil || err != utils.ErrPartiallyExecuted { + t.Errorf("Expected %+v, received %+v", utils.ErrPartiallyExecuted, err) + } +} + +func TestACHTTPPostID(t *testing.T) { + apAction := &engine.APAction{ + ID: "TestACHTTPPostID", + Type: utils.MetaHTTPPost, + } + http := &actHTTPPost{ + aCfg: apAction, + } + if rcv := http.id(); rcv != apAction.ID { + t.Errorf("Expected %+v, received %+v", apAction.ID, rcv) + } + + actESP := &actExport{ + aCfg: apAction, + } + if rcv := actESP.id(); rcv != apAction.ID { + t.Errorf("Expected %+v, received %+v", apAction.ID, rcv) + } +} diff --git a/actions/log_test.go b/actions/log_test.go new file mode 100644 index 000000000..d0d3a0abd --- /dev/null +++ b/actions/log_test.go @@ -0,0 +1,110 @@ +/* +Real-time Online/Offline Charging System (OerS) 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 actions + +import ( + "reflect" + "testing" + "time" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +func TestACExecuteActCDRLog(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + cfg.ActionSCfg().CDRsConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)} + cfg.TemplatesCfg()[utils.MetaCdrLog][0].Filters = []string{"invalid_filter_value"} + data := engine.NewInternalDB(nil, nil, true) + dm := engine.NewDataManager(data, cfg.CacheCfg(), nil) + fltr := engine.NewFilterS(cfg, nil, dm) + apAction := &engine.APAction{ + ID: "TEST_ACTION", + Type: utils.CDRLog, + } + + dataStorage := utils.MapStorage{ + utils.MetaReq: map[string]interface{}{ + utils.AccountField: "1001", + }, + utils.MetaOpts: map[string]interface{}{ + utils.Usage: 10 * time.Minute, + }, + } + + actCdrLG := &actCDRLog{ + config: cfg, + filterS: fltr, + aCfg: apAction, + } + expected := "NOT_FOUND:invalid_filter_value" + if err := actCdrLG.execute(nil, dataStorage, + utils.EmptyString); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } +} + +func TestACActLogger(t *testing.T) { + actLog := &actLog{ + aCfg: &engine.APAction{ + ID: "TEST_ACTION", + Type: utils.CDRLog, + }, + } + if rcv := actLog.id(); rcv != "TEST_ACTION" { + t.Errorf("Expected %+v, received %+v", "TEST_ACTION", rcv) + } + if rcv := actLog.cfg(); !reflect.DeepEqual(rcv, actLog.aCfg) { + t.Errorf("Expected %+v, received %+v", utils.ToJSON(actLog.aCfg), utils.ToJSON(rcv)) + } +} + +func TestACResetStatsAndThresholds(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + apAction := &engine.APAction{ + ID: "TEST_ACTION", + Type: utils.CDRLog, + } + actResStats := &actResetStat{ + tnt: "cgrates.org", + config: cfg, + aCfg: apAction, + } + + if rcv := actResStats.id(); rcv != "TEST_ACTION" { + t.Errorf("Expected %+v, received %+v", "TEST_ACTION", rcv) + } + if rcv := actResStats.cfg(); !reflect.DeepEqual(rcv, actResStats.aCfg) { + t.Errorf("Expected %+v, received %+v", utils.ToJSON(actResStats.aCfg), utils.ToJSON(rcv)) + } + + actResTh := &actResetThreshold{ + tnt: "cgrates.org", + config: cfg, + aCfg: apAction, + } + + if rcv := actResTh.id(); rcv != "TEST_ACTION" { + t.Errorf("Expected %+v, received %+v", "TEST_ACTION", rcv) + } + if rcv := actResTh.cfg(); !reflect.DeepEqual(rcv, actResTh.aCfg) { + t.Errorf("Expected %+v, received %+v", utils.ToJSON(actResTh.aCfg), utils.ToJSON(rcv)) + } +}