From e7d3aa6a2b2a18be475eae1618fd9840456af8ef Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Fri, 18 Mar 2022 18:13:30 +0200 Subject: [PATCH] Add cover tests in apis --- apis/chargers_test.go | 233 +++++++++++++++++++++++++++++++++++++++ apis/dispatchers_test.go | 26 +++++ apis/rates_test.go | 189 +++++++++++++++++++++++++++++++ 3 files changed, 448 insertions(+) diff --git a/apis/chargers_test.go b/apis/chargers_test.go index 63a9be83c..d9afbdb2e 100644 --- a/apis/chargers_test.go +++ b/apis/chargers_test.go @@ -19,10 +19,12 @@ along with this program. If not, see package apis import ( + "fmt" "reflect" "sort" "testing" + "github.com/cgrates/birpc" "github.com/cgrates/birpc/context" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" @@ -1095,3 +1097,234 @@ func TestChargersGetChargerProfileCheckErrors(t *testing.T) { dm.DataDB().Flush(utils.EmptyString) } + +func TestChargersNewChargerSv1(t *testing.T) { + engine.Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + dataDB := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(dataDB, cfg.CacheCfg(), nil) + chS := engine.NewChargerService(dm, nil, cfg, nil) + + exp := &ChargerSv1{ + cS: chS, + } + rcv := NewChargerSv1(chS) + + if !reflect.DeepEqual(rcv, exp) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", exp, rcv) + } +} + +func TestChargersAPIs(t *testing.T) { + engine.Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + cfg.GeneralCfg().DefaultCaching = utils.MetaNone + cfg.ChargerSCfg().AttributeSConns = []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)} + cfg.AttributeSCfg().Opts.ProcessRuns = []*utils.DynamicIntOpt{ + { + Value: 2, + }, + } + data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, cfg.CacheCfg(), nil) + fltrs := engine.NewFilterS(cfg, nil, dm) + + expEv := &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventTest", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProfileIDs: []string{"ATTR1", "ATTR2"}, + utils.MetaChargeID: "", + utils.OptsContext: utils.MetaChargers, + utils.Subsys: utils.MetaChargers, + utils.MetaRunID: "run_1", + }, + } + + mCC := &mockClientConn{ + calls: map[string]func(*context.Context, interface{}, interface{}) error{ + utils.AttributeSv1ProcessEvent: func(ctx *context.Context, args, reply interface{}) error { + expEv.APIOpts[utils.MetaChargeID] = args.(*utils.CGREvent).APIOpts[utils.MetaChargeID] + if !reflect.DeepEqual(args, expEv) { + return fmt.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(expEv), utils.ToJSON(args)) + } + return nil + }, + }, + } + rpcInternal := make(chan birpc.ClientConnector, 1) + rpcInternal <- mCC + cM := engine.NewConnManager(cfg) + cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes), utils.AttributeSv1, rpcInternal) + + adms := &AdminSv1{ + dm: dm, + cfg: cfg, + } + + argsCharger1 := &ChargerWithAPIOpts{ + ChargerProfile: &engine.ChargerProfile{ + Tenant: "cgrates.org", + ID: "CHARGER1", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, + RunID: "run_1", + AttributeIDs: []string{"ATTR1", "ATTR2"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, + }, + APIOpts: nil, + } + + var setReply string + if err := adms.SetChargerProfile(context.Background(), argsCharger1, &setReply); err != nil { + t.Error(err) + } else if setReply != "OK" { + t.Error("Unexpected reply returned:", setReply) + } + + argsCharger2 := &ChargerWithAPIOpts{ + ChargerProfile: &engine.ChargerProfile{ + Tenant: "cgrates.org", + ID: "CHARGER2", + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + RunID: "run_2", + AttributeIDs: []string{"ATTR3"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, + }, + APIOpts: nil, + } + + if err := adms.SetChargerProfile(context.Background(), argsCharger2, &setReply); err != nil { + t.Error(err) + } else if setReply != "OK" { + t.Error("Unexpected reply returned:", setReply) + } + + cS := engine.NewChargerService(dm, fltrs, cfg, cM) + cSv1 := NewChargerSv1(cS) + + argsGetForEvent := &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventTest", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + APIOpts: map[string]interface{}{}, + } + exp := engine.ChargerProfiles{ + { + + Tenant: "cgrates.org", + ID: "CHARGER2", + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + RunID: "run_2", + AttributeIDs: []string{"ATTR3"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, + }, + { + Tenant: "cgrates.org", + ID: "CHARGER1", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, + RunID: "run_1", + AttributeIDs: []string{"ATTR1", "ATTR2"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, + }, + } + var reply engine.ChargerProfiles + if err := cSv1.GetChargersForEvent(context.Background(), argsGetForEvent, &reply); err != nil { + t.Error(err) + } else { + if utils.ToJSON(reply) != utils.ToJSON(exp) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(exp), utils.ToJSON(reply)) + } + } + + argsCharger2 = &ChargerWithAPIOpts{ + ChargerProfile: &engine.ChargerProfile{ + Tenant: "cgrates.org", + ID: "CHARGER2", + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + RunID: "run_2", + AttributeIDs: []string{"ATTR3"}, + FilterIDs: []string{"*string:~*req.Account:1002"}, + }, + APIOpts: nil, + } + + if err := adms.SetChargerProfile(context.Background(), argsCharger2, &setReply); err != nil { + t.Error(err) + } else if setReply != "OK" { + t.Error("Unexpected reply returned:", setReply) + } + + argsProcessEv := &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventTest", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + APIOpts: map[string]interface{}{}, + } + expProcessEv := []*engine.ChrgSProcessEventReply{ + { + ChargerSProfile: "CHARGER1", + AlteredFields: []string{"*opts.*runID", "*opts.*chargeID"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventTest", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProfileIDs: []string{"ATTR1", "ATTR2"}, + utils.MetaChargeID: "", + utils.OptsContext: utils.MetaChargers, + utils.Subsys: utils.MetaChargers, + utils.MetaRunID: "run_1", + }, + }, + }, + } + var replyProcessEv []*engine.ChrgSProcessEventReply + if err := cSv1.ProcessEvent(context.Background(), argsProcessEv, &replyProcessEv); err != nil { + t.Error(err) + } else { + expProcessEv[0].CGREvent.APIOpts[utils.MetaChargeID] = replyProcessEv[0].CGREvent.APIOpts[utils.MetaChargeID] + if !reflect.DeepEqual(replyProcessEv, expProcessEv) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(expProcessEv), utils.ToJSON(replyProcessEv)) + } + } +} + +func TestChargersSv1Ping(t *testing.T) { + cSv1 := new(ChargerSv1) + var reply string + if err := cSv1.Ping(nil, nil, &reply); err != nil { + t.Error(err) + } else if reply != utils.Pong { + t.Errorf("Unexpected reply error") + } +} diff --git a/apis/dispatchers_test.go b/apis/dispatchers_test.go index aa00424e6..5e9c8870b 100644 --- a/apis/dispatchers_test.go +++ b/apis/dispatchers_test.go @@ -1429,3 +1429,29 @@ func TestDispatchersGetDispatcherHostsGetHostErr(t *testing.T) { dm.DataDB().Flush(utils.EmptyString) } + +func TestDispatchersSetDispatcherHostErr(t *testing.T) { + engine.Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + cfg.GeneralCfg().DefaultCaching = utils.MetaNone + adms := &AdminSv1{ + cfg: cfg, + } + + dspHost := &engine.DispatcherHostWithAPIOpts{ + DispatcherHost: &engine.DispatcherHost{ + RemoteHost: &config.RemoteHost{ + ID: "TEST", + }, + }, + } + + var reply string + experr := "SERVER_ERROR: NO_DATABASE_CONNECTION" + + if err := adms.SetDispatcherHost(context.Background(), dspHost, &reply); err == nil || + err.Error() != experr { + t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", experr, err) + } + +} diff --git a/apis/rates_test.go b/apis/rates_test.go index e65262062..b5f49dd30 100644 --- a/apis/rates_test.go +++ b/apis/rates_test.go @@ -2317,3 +2317,192 @@ func TestRatesGetRateProfileRatesCountErrMissing(t *testing.T) { t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) } } + +func TestRatesGetRateProfileRateIDsErrNotFound(t *testing.T) { + engine.Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + cfg.GeneralCfg().DefaultCaching = utils.MetaNone + + dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, nil), cfg.CacheCfg(), nil) + adms := &AdminSv1{ + cfg: cfg, + dm: dm, + } + + var reply []string + + if err := adms.GetRateProfileRateIDs(context.Background(), + &utils.ArgsSubItemIDs{ + Tenant: "cgrates.org", + ProfileID: "prfID", + }, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) + } + + dm.DataDB().Flush(utils.EmptyString) +} + +func TestRatesGetRateProfileRateIDsErrKeys(t *testing.T) { + engine.Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + cfg.GeneralCfg().DefaultCaching = utils.MetaNone + dbMock := &engine.DataDBMock{ + GetRateProfileRatesDrvF: func(ctx *context.Context, s1, s2, s3 string, b bool) ([]string, []*utils.Rate, error) { + return []string{}, nil, nil + }, + } + dm := engine.NewDataManager(dbMock, cfg.CacheCfg(), nil) + adms := &AdminSv1{ + cfg: cfg, + dm: dm, + } + + var reply []string + + if err := adms.GetRateProfileRateIDs(context.Background(), + &utils.ArgsSubItemIDs{ + Tenant: "cgrates.org", + ProfileID: "prfID", + }, &reply); err == nil || err != utils.ErrNotFound { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) + } + + dm.DataDB().Flush(utils.EmptyString) +} + +func TestRatesGetRateProfileRateIDsGetOptsErr(t *testing.T) { + engine.Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + cfg.GeneralCfg().DefaultCaching = utils.MetaNone + dbMock := &engine.DataDBMock{ + GetRateProfileRatesDrvF: func(ctx *context.Context, s1, s2, s3 string, b bool) ([]string, []*utils.Rate, error) { + return []string{"RATE1", "RATE2"}, []*utils.Rate{ + { + ID: "RATE1", + }, + { + ID: "RATE2", + }, + }, nil + }, + } + + dm := engine.NewDataManager(dbMock, cfg.CacheCfg(), nil) + adms := &AdminSv1{ + cfg: cfg, + dm: dm, + } + + var reply []string + experr := "cannot convert field: true to int" + + if err := adms.GetRateProfileRateIDs(context.Background(), + &utils.ArgsSubItemIDs{ + Tenant: "cgrates.org", + ProfileID: "prfID", + APIOpts: map[string]interface{}{ + utils.PageLimitOpt: true, + }, + }, &reply); err == nil || err.Error() != experr { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) + } + + dm.DataDB().Flush(utils.EmptyString) +} + +func TestRatesGetRateProfileRateIDsPaginateErr(t *testing.T) { + engine.Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + cfg.GeneralCfg().DefaultCaching = utils.MetaNone + dbMock := &engine.DataDBMock{ + GetRateProfileRatesDrvF: func(ctx *context.Context, s1, s2, s3 string, b bool) ([]string, []*utils.Rate, error) { + return []string{"RATE1", "RATE2"}, []*utils.Rate{ + { + ID: "RATE1", + }, + { + ID: "RATE2", + }, + }, nil + }, + } + + dm := engine.NewDataManager(dbMock, cfg.CacheCfg(), nil) + adms := &AdminSv1{ + cfg: cfg, + dm: dm, + } + + var reply []string + experr := `SERVER_ERROR: maximum number of items exceeded` + + if err := adms.GetRateProfileRateIDs(context.Background(), + &utils.ArgsSubItemIDs{ + ProfileID: "prfID", + APIOpts: map[string]interface{}{ + utils.PageLimitOpt: 2, + utils.PageOffsetOpt: 4, + utils.PageMaxItemsOpt: 5, + }, + }, &reply); err == nil || err.Error() != experr { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) + } + + dm.DataDB().Flush(utils.EmptyString) +} + +func TestRatesGetRateProfileRateIDsErrMissing(t *testing.T) { + engine.Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + cfg.GeneralCfg().DefaultCaching = utils.MetaNone + dataDB := engine.NewInternalDB(nil, nil, nil) + dm := engine.NewDataManager(dataDB, cfg.CacheCfg(), nil) + adms := &AdminSv1{ + cfg: cfg, + dm: dm, + } + + var reply []string + experr := `MANDATORY_IE_MISSING: [ProfileID]` + + if err := adms.GetRateProfileRateIDs(context.Background(), + &utils.ArgsSubItemIDs{ + Tenant: "cgrates.org", + }, &reply); err == nil || err.Error() != experr { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) + } + + dm.DataDB().Flush(utils.EmptyString) +} + +func TestRatesSetRateProfileErrConvertOverwriteOpt(t *testing.T) { + engine.Cache.Clear(nil) + cfg := config.NewDefaultCGRConfig() + cfg.GeneralCfg().DefaultCaching = utils.MetaNone + connMgr := engine.NewConnManager(cfg) + dataDB := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(dataDB, nil, connMgr) + admS := NewAdminSv1(cfg, dm, connMgr) + args := &utils.APIRateProfile{ + RateProfile: &utils.RateProfile{ + Tenant: "cgrates.org", + FilterIDs: []string{"*string:~*req.Subject:1001"}, + Rates: map[string]*utils.Rate{ + "RT_WEEK": { + ID: "RT_WEEK", + ActivationTimes: "* * * * *", + }, + }, + ID: "RateProfile", + }, + APIOpts: map[string]interface{}{ + utils.MetaRateSOverwrite: "invalid_opt", + }, + } + expected := `strconv.ParseBool: parsing "invalid_opt": invalid syntax` + var rtRply string + err := admS.SetRateProfile(context.Background(), args, &rtRply) + if err == nil || err.Error() != expected { + t.Errorf("expected <%+v>, \nreceived <%+v>", expected, err) + } +}