From 04390e6fb3ffdc1ab47cb2bcca1d1d23ce630053 Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Wed, 2 Jun 2021 13:45:59 +0300 Subject: [PATCH] Add coverage tests for engine/chargers.go --- engine/chargers_test.go | 213 ++++++++++++++ engine/datadbmock.go | 7 +- engine/z_chargers_test.go | 594 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 812 insertions(+), 2 deletions(-) create mode 100644 engine/z_chargers_test.go diff --git a/engine/chargers_test.go b/engine/chargers_test.go index ae03e2274..83beb5312 100644 --- a/engine/chargers_test.go +++ b/engine/chargers_test.go @@ -18,7 +18,11 @@ along with this program. If not, see package engine import ( + "bytes" + "log" + "os" "reflect" + "strings" "testing" "time" @@ -462,3 +466,212 @@ func TestChargerProcessEvent(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v ", utils.ToJSON(rpl[0]), utils.ToJSON(rcv[0])) } } + +func TestChargersmatchingChargerProfilesForEventChargerProfileNotFound(t *testing.T) { + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().StringIndexedFields = &[]string{ + "string", + } + defaultCfg.ChargerSCfg().PrefixIndexedFields = &[]string{"prefix"} + defaultCfg.ChargerSCfg().SuffixIndexedFields = &[]string{"suffix"} + defaultCfg.ChargerSCfg().IndexedSelects = false + defaultCfg.ChargerSCfg().NestedFields = false + + dataDB := NewInternalDB(nil, nil, true) + dmCharger := NewDataManager(dataDB, config.CgrConfig().CacheCfg(), nil) + cS := &ChargerService{ + dm: dmCharger, + filterS: &FilterS{ + dm: dmCharger, + cfg: defaultCfg, + }, + cfg: defaultCfg, + } + cgrEv := &utils.CGREvent{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "cgrEvID", + Event: map[string]interface{}{ + "Charger": "ChargerProfile1", + utils.AnswerTime: time.Date(2021, 4, 1, 10, 0, 0, 0, time.UTC), + "UsageInterval": "1s", + utils.Weight: "10.0", + }, + APIOpts: map[string]interface{}{ + utils.Subsys: utils.MetaChargers, + }, + } + + experr := utils.ErrNotFound + rcv, err := cS.matchingChargerProfilesForEvent("tnt", cgrEv) + + if err == nil || err != experr { + t.Fatalf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + + if rcv != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) + } +} + +func TestChargersmatchingChargerProfilesForEventDoesNotPass(t *testing.T) { + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().StringIndexedFields = &[]string{ + "string", + } + defaultCfg.ChargerSCfg().PrefixIndexedFields = &[]string{"prefix"} + defaultCfg.ChargerSCfg().SuffixIndexedFields = &[]string{"suffix"} + defaultCfg.ChargerSCfg().IndexedSelects = false + defaultCfg.ChargerSCfg().NestedFields = false + + dataDB := NewInternalDB(nil, nil, true) + dmCharger := NewDataManager(dataDB, config.CgrConfig().CacheCfg(), nil) + cS := &ChargerService{ + dm: dmCharger, + filterS: &FilterS{ + dm: dmCharger, + cfg: defaultCfg, + }, + cfg: defaultCfg, + } + cgrEv := &utils.CGREvent{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "cgrEvID", + Event: map[string]interface{}{ + "Charger": "ChargerProfile1", + utils.AnswerTime: time.Date(2021, 4, 1, 10, 0, 0, 0, time.UTC), + "UsageInterval": "1s", + utils.Weight: "10.0", + }, + APIOpts: map[string]interface{}{ + utils.Subsys: utils.MetaChargers, + }, + } + + experr := utils.ErrNotFound + rcv, err := cS.matchingChargerProfilesForEvent(cgrEv.Tenant, cgrEv) + + if err == nil || err != experr { + t.Fatalf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + + if rcv != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) + } +} + +func TestChargersmatchingChargerProfilesForEventErrGetChPrf(t *testing.T) { + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().StringIndexedFields = &[]string{ + "string", + } + defaultCfg.ChargerSCfg().PrefixIndexedFields = &[]string{"prefix"} + defaultCfg.ChargerSCfg().SuffixIndexedFields = &[]string{"suffix"} + defaultCfg.ChargerSCfg().IndexedSelects = false + defaultCfg.ChargerSCfg().NestedFields = false + + dbm := &DataDBMock{ + GetKeysForPrefixF: func(ctx *context.Context, s string) ([]string, error) { + return []string{":"}, nil + }, + } + dmCharger := NewDataManager(dbm, defaultCfg.CacheCfg(), nil) + cS := &ChargerService{ + dm: dmCharger, + filterS: &FilterS{ + dm: dmCharger, + cfg: defaultCfg, + }, + cfg: defaultCfg, + } + cgrEv := &utils.CGREvent{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "cgrEvID", + Event: map[string]interface{}{ + "Charger": "ChargerProfile1", + utils.AnswerTime: time.Date(2021, 4, 1, 10, 0, 0, 0, time.UTC), + "UsageInterval": "1s", + utils.Weight: "10.0", + }, + APIOpts: map[string]interface{}{ + utils.Subsys: utils.MetaChargers, + }, + } + + experr := utils.ErrNotImplemented + rcv, err := cS.matchingChargerProfilesForEvent(cgrEv.Tenant, cgrEv) + + if err == nil || err != experr { + t.Fatalf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + + if rcv != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) + } + +} + +func TestChargersprocessEvent(t *testing.T) { + defaultCfg := config.NewDefaultCGRConfig() + cS := &ChargerService{ + cfg: defaultCfg, + } + cgrEv := &utils.CGREvent{ + Tenant: "cgrates.org", + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 2, + }, + } + + experr := "NO_DATABASE_CONNECTION" + rcv, err := cS.processEvent(cgrEv.Tenant, cgrEv) + + if err == nil || err.Error() != experr { + t.Fatalf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + + if rcv != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) + } +} + +func TestChargersV1ProcessEventMissingArgs(t *testing.T) { + cS := &ChargerService{} + args := &utils.CGREvent{} + var reply *[]*ChrgSProcessEventReply + + experr := "MANDATORY_IE_MISSING: [Event]" + err := cS.V1ProcessEvent(args, reply) + + if err == nil || err.Error() != experr { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } +} + +func TestChargersShutdown(t *testing.T) { + cS := &ChargerService{} + + utils.Logger.SetLogLevel(6) + utils.Logger.SetSyslog(nil) + + var buf bytes.Buffer + log.SetOutput(&buf) + defer func() { + log.SetOutput(os.Stderr) + }() + + exp := []string{ + "CGRateS <> [INFO] shutdown initialized", + "CGRateS <> [INFO] shutdown complete", + } + cS.Shutdown() + rcv := strings.Split(buf.String(), "\n") + + for i := 0; i < 2; i++ { + rcv[i] = rcv[i][20:] + if rcv[i] != exp[i] { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", exp[i], rcv[i]) + } + } + + utils.Logger.SetLogLevel(0) +} diff --git a/engine/datadbmock.go b/engine/datadbmock.go index 9b2cd1084..d08bef64b 100644 --- a/engine/datadbmock.go +++ b/engine/datadbmock.go @@ -35,7 +35,7 @@ type DataDBMock struct { RemoveAttributeProfileDrvF func(ctx *context.Context, str1 string, str2 string) error SetLoadIDsDrvF func(ctx *context.Context, loadIDs map[string]int64) error GetFilterDrvF func(ctx *context.Context, str1 string, str2 string) (*Filter, error) - GetChargerProfileDrvF func(*context.Context, string, string) (*ChargerProfile, error) + GetChargerProfileDrvF func(tnt, id string) (*ChargerProfile, error) GetThresholdProfileDrvF func(ctx *context.Context, tenant, id string) (tp *ThresholdProfile, err error) SetThresholdProfileDrvF func(ctx *context.Context, tp *ThresholdProfile) (err error) RemThresholdProfileDrvF func(ctx *context.Context, tenant, id string) (err error) @@ -294,7 +294,10 @@ func (dbM *DataDBMock) RemoveAttributeProfileDrv(ctx *context.Context, str1 stri return utils.ErrNotImplemented } -func (dbM *DataDBMock) GetChargerProfileDrv(string, string) (*ChargerProfile, error) { +func (dbM *DataDBMock) GetChargerProfileDrv(tnt, id string) (*ChargerProfile, error) { + if dbM.GetChargerProfileDrvF != nil { + return dbM.GetChargerProfileDrvF(tnt, id) + } return nil, utils.ErrNotImplemented } diff --git a/engine/z_chargers_test.go b/engine/z_chargers_test.go new file mode 100644 index 000000000..6e3d7071f --- /dev/null +++ b/engine/z_chargers_test.go @@ -0,0 +1,594 @@ +/* +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 ( + "fmt" + "reflect" + "testing" + "time" + + "github.com/cgrates/birpc" + "github.com/cgrates/birpc/context" + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" +) + +func TestChargersmatchingChargerProfilesForEventErrPass(t *testing.T) { + Cache.Clear(nil) + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().IndexedSelects = false + + dbm := &DataDBMock{ + GetChargerProfileDrvF: func(s1, s2 string) (*ChargerProfile, error) { + return &ChargerProfile{ + Tenant: s1, + ID: s2, + RunID: utils.MetaDefault, + FilterIDs: []string{"fltr1"}, + }, nil + }, + GetKeysForPrefixF: func(ctx *context.Context, s string) ([]string, error) { + return []string{s + "cgrates.org:chr1"}, nil + }, + GetFilterDrvF: func(ctx *context.Context, s1, s2 string) (*Filter, error) { + return nil, utils.ErrNotImplemented + }, + } + dmFilter := NewDataManager(dbm, defaultCfg.CacheCfg(), nil) + cS := &ChargerService{ + dm: dmFilter, + filterS: &FilterS{ + dm: dmFilter, + cfg: defaultCfg, + }, + cfg: defaultCfg, + } + cgrEv := &utils.CGREvent{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "cgrEvID", + Event: map[string]interface{}{ + "Charger": "ChargerProfile1", + utils.AnswerTime: time.Date(2021, 4, 19, 12, 0, 0, 0, time.UTC), + "UsageInterval": "10s", + utils.Weight: "10.0", + }, + APIOpts: map[string]interface{}{ + utils.Subsys: utils.MetaChargers, + }, + } + + experr := utils.ErrNotImplemented + rcv, err := cS.matchingChargerProfilesForEvent(cgrEv.Tenant, cgrEv) + + if err == nil || err != experr { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + + if rcv != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) + } +} + +func TestChargersprocessEventCallNilErr(t *testing.T) { + Cache.Clear(nil) + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().IndexedSelects = false + defaultCfg.ChargerSCfg().AttributeSConns = []string{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, defaultCfg.CacheCfg(), nil) + cP := &ChargerProfile{ + Tenant: "cgrates.org", + ID: "1001", + RunID: utils.MetaDefault, + FilterIDs: []string{"*string:~*req.Account:1001"}, + } + if err := dm.SetChargerProfile(cP, true); err != nil { + t.Fatal(err) + } + + ccM := &ccMock{ + calls: map[string]func(ctx *context.Context, args interface{}, reply interface{}) error{ + utils.AttributeSv1ProcessEvent: func(ctx *context.Context, args, reply interface{}) error { + rply := AttrSProcessEventReply{ + AlteredFields: []string{utils.AccountField}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + } + *reply.(*AttrSProcessEventReply) = rply + return nil + }, + }, + } + rpcInternal := make(chan birpc.ClientConnector, 1) + rpcInternal <- ccM + + cS := &ChargerService{ + dm: dm, + filterS: &FilterS{ + dm: dm, + cfg: defaultCfg, + }, + cfg: defaultCfg, + connMgr: NewConnManager(defaultCfg, map[string]chan birpc.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes): rpcInternal, + }), + } + + cgrEv := &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + } + + exp := []*ChrgSProcessEventReply{ + { + ChargerSProfile: "1001", + AlteredFields: []string{utils.MetaReqRunID, utils.AccountField}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + }, + } + rcv, err := cS.processEvent(cgrEv.Tenant, cgrEv) + + if err != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) + } + + if !reflect.DeepEqual(exp, rcv) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(exp), utils.ToJSON(rcv)) + } + + if err := dm.DataDB().Flush(""); err != nil { + t.Error(err) + } + +} + +func TestChargersprocessEventCallErr(t *testing.T) { + Cache.Clear(nil) + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().IndexedSelects = false + defaultCfg.ChargerSCfg().AttributeSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, defaultCfg.CacheCfg(), nil) + cP := &ChargerProfile{ + Tenant: "cgrates.org", + ID: "1001", + RunID: utils.MetaDefault, + FilterIDs: []string{"*string:~*req.Account:1001"}, + } + if err := dm.SetChargerProfile(cP, true); err != nil { + t.Fatal(err) + } + + ccM := &ccMock{ + calls: map[string]func(ctx *context.Context, args interface{}, reply interface{}) error{ + utils.AttributeSv1ProcessEvent: func(ctx *context.Context, args, reply interface{}) error { + return utils.ErrNotFound + }, + }, + } + rpcInternal := make(chan birpc.ClientConnector, 1) + rpcInternal <- ccM + + cS := &ChargerService{ + dm: dm, + filterS: &FilterS{ + dm: dm, + cfg: defaultCfg, + }, + cfg: defaultCfg, + connMgr: NewConnManager(defaultCfg, map[string]chan birpc.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes): rpcInternal, + }), + } + + cgrEv := &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + } + + exp := []*ChrgSProcessEventReply{ + { + ChargerSProfile: "1001", + AlteredFields: []string{utils.MetaReqRunID}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + "RunID": utils.MetaDefault, + }, + APIOpts: map[string]interface{}{ + utils.Subsys: utils.MetaChargers, + utils.OptsContext: utils.MetaChargers, + }, + }, + }, + } + rcv, err := cS.processEvent(cgrEv.Tenant, cgrEv) + + if err != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) + } + + if !reflect.DeepEqual(exp, rcv) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(exp), utils.ToJSON(rcv)) + } + + if err := dm.DataDB().Flush(""); err != nil { + t.Error(err) + } +} + +func TestChargersV1ProcessEventErrNotFound(t *testing.T) { + Cache.Clear(nil) + dataDB := NewInternalDB(nil, nil, true) + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().IndexedSelects = false + defaultCfg.ChargerSCfg().AttributeSConns = []string{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + dm := NewDataManager(dataDB, defaultCfg.CacheCfg(), nil) + + cP := &ChargerProfile{ + Tenant: "cgrates.org", + ID: "1001", + RunID: utils.MetaDefault, + FilterIDs: []string{"*string:~*req.Account:1001"}, + } + if err := dm.SetChargerProfile(cP, true); err != nil { + t.Fatal(err) + } + + ccM := &ccMock{ + calls: map[string]func(ctx *context.Context, args interface{}, reply interface{}) error{ + utils.AttributeSv1ProcessEvent: func(ctx *context.Context, args, reply interface{}) error { + rply := AttrSProcessEventReply{ + AlteredFields: []string{utils.AccountField}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + } + *reply.(*AttrSProcessEventReply) = rply + return nil + }, + }, + } + rpcInternal := make(chan birpc.ClientConnector, 1) + rpcInternal <- ccM + + cS := &ChargerService{ + dm: dm, + filterS: &FilterS{ + dm: dm, + cfg: defaultCfg, + }, + cfg: defaultCfg, + connMgr: NewConnManager(defaultCfg, map[string]chan birpc.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes): rpcInternal, + }), + } + args := &utils.CGREvent{ + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1002", + }, + } + reply := &[]*ChrgSProcessEventReply{} + + experr := utils.ErrNotFound + err := cS.V1ProcessEvent(args, reply) + + if err == nil || err != experr { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + + if err := dm.DataDB().Flush(""); err != nil { + t.Error(err) + } +} + +func TestChargersV1ProcessEventErrOther(t *testing.T) { + Cache.Clear(nil) + dataDB := NewInternalDB(nil, nil, true) + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().IndexedSelects = false + defaultCfg.ChargerSCfg().AttributeSConns = []string{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + dm := NewDataManager(dataDB, defaultCfg.CacheCfg(), nil) + + cP := &ChargerProfile{ + Tenant: "cgrates.org", + ID: "1001", + RunID: utils.MetaDefault, + FilterIDs: []string{"*string:~*req.Account:1001"}, + } + if err := dm.SetChargerProfile(cP, true); err != nil { + t.Fatal(err) + } + + ccM := &ccMock{ + calls: map[string]func(ctx *context.Context, args interface{}, reply interface{}) error{ + "invalidMethod": func(ctx *context.Context, args, reply interface{}) error { + rply := AttrSProcessEventReply{ + AlteredFields: []string{utils.AccountField}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + } + *reply.(*AttrSProcessEventReply) = rply + return nil + }, + }, + } + rpcInternal := make(chan birpc.ClientConnector, 1) + rpcInternal <- ccM + + cS := &ChargerService{ + dm: dm, + filterS: &FilterS{ + dm: dm, + cfg: defaultCfg, + }, + cfg: defaultCfg, + connMgr: NewConnManager(defaultCfg, map[string]chan birpc.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes): rpcInternal, + }), + } + args := &utils.CGREvent{ + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + } + reply := &[]*ChrgSProcessEventReply{} + + exp := &[]*ChrgSProcessEventReply{} + experr := fmt.Sprintf("SERVER_ERROR: %s", rpcclient.ErrUnsupporteServiceMethod) + err := cS.V1ProcessEvent(args, reply) + + if err == nil || err.Error() != experr { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + + if !reflect.DeepEqual(reply, exp) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(exp), utils.ToJSON(reply)) + } + + if err := dm.DataDB().Flush(""); err != nil { + t.Error(err) + } +} + +func TestChargersV1ProcessEvent(t *testing.T) { + Cache.Clear(nil) + dataDB := NewInternalDB(nil, nil, true) + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().IndexedSelects = false + defaultCfg.ChargerSCfg().AttributeSConns = []string{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + dm := NewDataManager(dataDB, defaultCfg.CacheCfg(), nil) + + cP := &ChargerProfile{ + Tenant: "cgrates.org", + ID: "1001", + RunID: utils.MetaDefault, + FilterIDs: []string{"*string:~*req.Account:1001"}, + } + if err := dm.SetChargerProfile(cP, true); err != nil { + t.Fatal(err) + } + + ccM := &ccMock{ + calls: map[string]func(ctx *context.Context, args interface{}, reply interface{}) error{ + utils.AttributeSv1ProcessEvent: func(ctx *context.Context, args, reply interface{}) error { + rply := AttrSProcessEventReply{ + AlteredFields: []string{utils.AccountField}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + } + *reply.(*AttrSProcessEventReply) = rply + return nil + }, + }, + } + rpcInternal := make(chan birpc.ClientConnector, 1) + rpcInternal <- ccM + + cS := &ChargerService{ + dm: dm, + filterS: &FilterS{ + dm: dm, + cfg: defaultCfg, + }, + cfg: defaultCfg, + connMgr: NewConnManager(defaultCfg, map[string]chan birpc.ClientConnector{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes): rpcInternal, + }), + } + args := &utils.CGREvent{ + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + } + reply := &[]*ChrgSProcessEventReply{} + + exp := &[]*ChrgSProcessEventReply{ + { + ChargerSProfile: "1001", + AlteredFields: []string{utils.MetaReqRunID, utils.AccountField}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + }, + } + err := cS.V1ProcessEvent(args, reply) + + if err != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) + } + + if !reflect.DeepEqual(reply, exp) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(exp), utils.ToJSON(reply)) + } + + if err := dm.DataDB().Flush(""); err != nil { + t.Error(err) + } +} + +func TestChargersV1GetChargersForEventNilErr(t *testing.T) { + Cache.Clear(nil) + dataDB := NewInternalDB(nil, nil, true) + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().IndexedSelects = false + defaultCfg.ChargerSCfg().AttributeSConns = []string{ + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + dm := NewDataManager(dataDB, defaultCfg.CacheCfg(), nil) + + cP := &ChargerProfile{ + Tenant: "cgrates.org", + ID: "1001", + RunID: utils.MetaDefault, + FilterIDs: []string{"*string:~*req.Account:1001"}, + } + if err := dm.SetChargerProfile(cP, true); err != nil { + t.Fatal(err) + } + + cS := &ChargerService{ + dm: dm, + filterS: &FilterS{ + dm: dm, + cfg: defaultCfg, + }, + cfg: defaultCfg, + } + args := &utils.CGREvent{ + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + } + reply := &ChargerProfiles{} + + exp := &ChargerProfiles{ + { + Tenant: "cgrates.org", + ID: "1001", + FilterIDs: []string{"*string:~*req.Account:1001"}, + RunID: "*default", + }, + } + err := cS.V1GetChargersForEvent(args, reply) + + if err != nil { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) + } + + if !reflect.DeepEqual(reply, exp) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(exp), utils.ToJSON(reply)) + } + + if err := dm.DataDB().Flush(""); err != nil { + t.Error(err) + } +} + +func TestChargersV1GetChargersForEventErr(t *testing.T) { + Cache.Clear(nil) + defaultCfg := config.NewDefaultCGRConfig() + defaultCfg.ChargerSCfg().IndexedSelects = false + + dbm := &DataDBMock{ + GetKeysForPrefixF: func(ctx *context.Context, s string) ([]string, error) { + return []string{":"}, nil + }, + } + dm := NewDataManager(dbm, defaultCfg.CacheCfg(), nil) + + cS := &ChargerService{ + dm: dm, + filterS: &FilterS{ + dm: dm, + cfg: defaultCfg, + }, + cfg: defaultCfg, + } + args := &utils.CGREvent{ + ID: "cgrEvID", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + } + reply := &ChargerProfiles{} + + exp := &ChargerProfiles{} + experr := fmt.Sprintf("SERVER_ERROR: %s", utils.ErrNotImplemented) + err := cS.V1GetChargersForEvent(args, reply) + + if err == nil || err.Error() != experr { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + + if !reflect.DeepEqual(reply, exp) { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(exp), utils.ToJSON(reply)) + } +}