diff --git a/engine/thresholds_test.go b/engine/thresholds_test.go index 0b52493ab..872b2a1c7 100644 --- a/engine/thresholds_test.go +++ b/engine/thresholds_test.go @@ -18,7 +18,11 @@ along with this program. If not, see package engine import ( + "bytes" + "log" + "os" "reflect" + "strings" "testing" "time" @@ -1129,3 +1133,835 @@ func TestThresholdsUpdateThreshold(t *testing.T) { t.Fatal(err) } } + +// func TestThresholdsProcessEventAccountUpdateErrPartExec(t *testing.T) { +// utils.Logger.SetLogLevel(4) +// utils.Logger.SetSyslog(nil) + +// var buf bytes.Buffer +// log.SetOutput(&buf) +// defer func() { +// log.SetOutput(os.Stderr) +// }() + +// thPrf := &ThresholdProfile{ +// Tenant: "cgrates.org", +// ID: "TH1", +// FilterIDs: []string{"*string:~*req.Account:1001"}, +// MinHits: 2, +// MaxHits: 5, +// Weight: 10, +// ActionIDs: []string{"actPrf"}, +// } +// th := &Threshold{ +// Tenant: "cgrates.org", +// ID: "TH1", +// Hits: 2, +// tPrfl: thPrf, +// } + +// args := &ThresholdsArgsProcessEvent{ +// ThresholdIDs: []string{"TH1"}, +// CGREvent: &utils.CGREvent{ +// Tenant: "cgrates.org", +// ID: "ThresholdProcessEvent", +// Event: map[string]interface{}{ +// utils.AccountField: "1001", +// }, +// APIOpts: map[string]interface{}{ +// utils.MetaEventType: utils.AccountUpdate, +// }, +// }, +// } +// expLog := `[WARNING] failed executing actions: actPrf, error: NOT_FOUND` +// if err := processEventWithThreshold(context.Background(), args, dm); err == nil || +// err != utils.ErrPartiallyExecuted { +// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrPartiallyExecuted, err) +// } + +// if rcvLog := buf.String(); !strings.Contains(rcvLog, expLog) { +// t.Errorf("expected log <%+v> \nto be included in: <%+v>", expLog, rcvLog) +// } +// utils.Logger.SetLogLevel(0) +// } + +// func TestThresholdsProcessEventAsyncExecErr(t *testing.T) { +// utils.Logger.SetLogLevel(4) +// utils.Logger.SetSyslog(nil) + +// var buf bytes.Buffer +// log.SetOutput(&buf) +// defer func() { +// log.SetOutput(os.Stderr) +// }() + +// thPrf := &ThresholdProfile{ +// Tenant: "cgrates.org", +// ID: "TH1", +// FilterIDs: []string{"*string:~*req.Account:1001"}, +// MinHits: 2, +// MaxHits: 5, +// Weight: 10, +// ActionIDs: []string{"actPrf"}, +// Async: true, +// } +// th := &Threshold{ +// Tenant: "cgrates.org", +// ID: "TH1", +// Hits: 2, +// tPrfl: thPrf, +// } + +// args := &ThresholdsArgsProcessEvent{ +// ThresholdIDs: []string{"TH1"}, +// CGREvent: &utils.CGREvent{ +// Tenant: "cgrates.org", +// ID: "ThresholdProcessEvent", +// Event: map[string]interface{}{ +// utils.AccountField: "1001", +// }, +// }, +// } +// expLog := `[WARNING] failed executing actions: actPrf, error: NOT_FOUND` +// if err := processEventWithThreshold(args, dm); err != nil { +// t.Error(err) +// } +// time.Sleep(10 * time.Millisecond) +// if rcvLog := buf.String(); !strings.Contains(rcvLog, expLog) { +// t.Errorf("expected log <%+v> \nto be included in: <%+v>", expLog, rcvLog) +// } + +// utils.Logger.SetLogLevel(0) +// } + +// func TestThresholdsProcessEvent3(t *testing.T) { +// thPrf := &ThresholdProfile{ +// Tenant: "cgrates.org", +// ID: "TH1", +// FilterIDs: []string{"*string:~*req.Account:1001"}, +// MinHits: 3, +// MaxHits: 5, +// Weight: 10, +// ActionIDs: []string{"actPrf"}, +// } +// th := &Threshold{ +// Tenant: "cgrates.org", +// ID: "TH1", +// Hits: 2, +// tPrfl: thPrf, +// } + +// args := &ThresholdsArgsProcessEvent{ +// ThresholdIDs: []string{"TH1"}, +// CGREvent: &utils.CGREvent{ +// Tenant: "cgrates.org", +// ID: "ThresholdProcessEvent", +// Event: map[string]interface{}{ +// utils.AccountField: "1001", +// }, +// APIOpts: map[string]interface{}{ +// utils.MetaEventType: utils.AccountUpdate, +// }, +// }, +// } +// if err := processEventWithThreshold(args, dm); err != nil { +// t.Error(err) +// } +// } + +func TestThresholdsShutdown(t *testing.T) { + utils.Logger.SetLogLevel(6) + utils.Logger.SetSyslog(nil) + + var buf bytes.Buffer + log.SetOutput(&buf) + defer func() { + log.SetOutput(os.Stderr) + }() + + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + tS := NewThresholdService(dm, cfg, nil, nil) + + expLog1 := `[INFO] shutdown initialized` + expLog2 := `[INFO] shutdown complete` + tS.Shutdown(context.Background()) + + if rcvLog := buf.String(); !strings.Contains(rcvLog, expLog1) || + !strings.Contains(rcvLog, expLog2) { + t.Errorf("expected logs <%+v> and <%+v> \n to be included in <%+v>", + expLog1, expLog2, rcvLog) + } + utils.Logger.SetLogLevel(0) +} + +func TestThresholdsStoreThresholdsOK(t *testing.T) { + tmp := Cache + defer func() { + Cache = tmp + }() + + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + tS := NewThresholdService(dm, cfg, nil, nil) + + value := &Threshold{ + dirty: utils.BoolPointer(true), + Tenant: "cgrates.org", + ID: "TH1", + Hits: 2, + } + + Cache.SetWithoutReplicate(utils.CacheThresholds, "TH1", value, nil, true, + utils.NonTransactional) + tS.storedTdIDs.Add("TH1") + exp := &Threshold{ + dirty: utils.BoolPointer(false), + Tenant: "cgrates.org", + ID: "TH1", + Hits: 2, + } + tS.storeThresholds(context.Background()) + + if rcv, err := tS.dm.GetThreshold(context.Background(), "cgrates.org", "TH1", true, false, + utils.NonTransactional); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(rcv, exp) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(exp), utils.ToJSON(rcv)) + } + + Cache.Remove(context.Background(), utils.CacheThresholds, "TH1", true, utils.NonTransactional) +} + +func TestThresholdsStoreThresholdsStoreThErr(t *testing.T) { + tmp := Cache + defer func() { + Cache = tmp + }() + + utils.Logger.SetLogLevel(4) + utils.Logger.SetSyslog(nil) + + var buf bytes.Buffer + log.SetOutput(&buf) + defer func() { + log.SetOutput(os.Stderr) + }() + + cfg := config.NewDefaultCGRConfig() + tS := NewThresholdService(nil, cfg, nil, nil) + + value := &Threshold{ + dirty: utils.BoolPointer(true), + Tenant: "cgrates.org", + ID: "TH1", + Hits: 2, + } + + Cache.SetWithoutReplicate(utils.CacheThresholds, "TH1", value, nil, true, + utils.NonTransactional) + tS.storedTdIDs.Add("TH1") + exp := utils.StringSet{ + "TH1": struct{}{}, + } + expLog := `[WARNING] failed saving Threshold with tenant: cgrates.org and ID: TH1, error: NO_DATABASE_CONNECTION` + tS.storeThresholds(context.Background()) + + if !reflect.DeepEqual(tS.storedTdIDs, exp) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", exp, tS.storedTdIDs) + } + if rcvLog := buf.String(); !strings.Contains(rcvLog, expLog) { + t.Errorf("expected log <%+v>\n to be in included in: <%+v>", expLog, rcvLog) + } + + utils.Logger.SetLogLevel(0) + Cache.Remove(context.Background(), utils.CacheThresholds, "TH1", true, utils.NonTransactional) +} + +func TestThresholdsStoreThresholdsCacheGetErr(t *testing.T) { + tmp := Cache + defer func() { + Cache = tmp + }() + + utils.Logger.SetLogLevel(4) + utils.Logger.SetSyslog(nil) + + var buf bytes.Buffer + log.SetOutput(&buf) + defer func() { + log.SetOutput(os.Stderr) + }() + + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + tS := NewThresholdService(dm, cfg, nil, nil) + + value := &Threshold{ + dirty: utils.BoolPointer(true), + Tenant: "cgrates.org", + ID: "TH1", + Hits: 2, + } + + Cache.SetWithoutReplicate(utils.CacheThresholds, "TH2", value, nil, true, + utils.NonTransactional) + tS.storedTdIDs.Add("TH1") + expLog := `[WARNING] failed retrieving from cache treshold with ID: TH1` + tS.storeThresholds(context.Background()) + + if rcvLog := buf.String(); !strings.Contains(rcvLog, expLog) { + t.Errorf("expected <%+v> \nto be included in: <%+v>", expLog, rcvLog) + } + + utils.Logger.SetLogLevel(0) + Cache.Remove(context.Background(), utils.CacheThresholds, "TH2", true, utils.NonTransactional) +} + +func TestThresholdsStoreThresholdNilDirtyField(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + tS := NewThresholdService(dm, cfg, nil, nil) + + th := &Threshold{ + Tenant: "cgrates.org", + ID: "TH1", + Hits: 2, + } + + if err := tS.StoreThreshold(context.Background(), th); err != nil { + t.Error(err) + } +} + +func TestThresholdsSetCloneable(t *testing.T) { + args := &ThresholdsArgsProcessEvent{ + ThresholdIDs: []string{"THD_ID"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventTest", + Event: map[string]interface{}{}, + }, + clnb: false, + } + + exp := &ThresholdsArgsProcessEvent{ + ThresholdIDs: []string{"THD_ID"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventTest", + Event: map[string]interface{}{}, + }, + clnb: true, + } + args.SetCloneable(true) + + if !reflect.DeepEqual(args, exp) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", exp, args) + } +} + +func TestThresholdsRPCClone(t *testing.T) { + args := &ThresholdsArgsProcessEvent{ + ThresholdIDs: []string{"THD_ID"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventTest", + Event: make(map[string]interface{}), + APIOpts: make(map[string]interface{}), + }, + clnb: true, + } + + exp := &ThresholdsArgsProcessEvent{ + ThresholdIDs: []string{"THD_ID"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventTest", + Event: make(map[string]interface{}), + APIOpts: make(map[string]interface{}), + }, + } + + if out, err := args.RPCClone(); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(out.(*ThresholdsArgsProcessEvent), exp) { + t.Errorf("expected: <%T>, \nreceived: <%T>", + args, exp) + } +} + +func TestThresholdsProcessEventStoreThOK(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + cfg.ThresholdSCfg().StoreInterval = -1 + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + filterS := NewFilterS(cfg, nil, dm) + tS := NewThresholdService(dm, cfg, filterS, nil) + + thPrf := &ThresholdProfile{ + Tenant: "cgrates.org", + ID: "TH2", + FilterIDs: []string{"*string:~*req.Account:1001"}, + MinHits: 2, + MaxHits: 5, + Weight: 10, + Blocker: true, + } + + if err := dm.SetThresholdProfile(context.Background(), thPrf, true); err != nil { + t.Error(err) + } + + args := &ThresholdsArgsProcessEvent{ + ThresholdIDs: []string{"TH2"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "ThdProcessEvent", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + } + exp := &Threshold{ + Tenant: "cgrates.org", + ID: "TH2", + Hits: 1, + } + expIDs := []string{"TH2"} + if rcvIDs, err := tS.processEvent(context.Background(), args.Tenant, args); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(rcvIDs, expIDs) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", expIDs, rcvIDs) + } else if rcv, err := tS.dm.GetThreshold(context.Background(), "cgrates.org", "TH2", true, false, + utils.NonTransactional); err != nil { + t.Error(err) + } else { + rcv.tPrfl = nil + rcv.dirty = nil + var snooze time.Time + rcv.Snooze = snooze + if !reflect.DeepEqual(rcv, exp) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", exp, rcv) + } + } + +} + +// func TestThresholdsProcessEventMaxHitsDMErr(t *testing.T) { +// utils.Logger.SetLogLevel(4) +// utils.Logger.SetSyslog(nil) + +// var buf bytes.Buffer +// log.SetOutput(&buf) +// defer func() { +// log.SetOutput(os.Stderr) +// }() + +// cfg := config.NewDefaultCGRConfig() +// data := NewInternalDB(nil, nil, true) +// dm := NewDataManager(data, cfg.CacheCfg(), nil) +// filterS := NewFilterS(cfg, nil, dm) +// tS := NewThresholdService(nil, cfg, filterS, nil) + +// thPrf := &ThresholdProfile{ +// Tenant: "cgrates.org", +// ID: "TH3", +// FilterIDs: []string{"*string:~*req.Account:1001"}, +// MinHits: 2, +// MaxHits: 5, +// Weight: 10, +// Blocker: true, +// } +// th := &Threshold{ +// Tenant: "cgrates.org", +// ID: "TH3", +// Hits: 4, +// tPrfl: thPrf, +// } + +// if err := dm.SetThresholdProfile(context.Background(), thPrf, true); err != nil { +// t.Error(err) +// } +// if err := dm.SetThreshold(context.Background(), th); err != nil { +// t.Error(err) +// } + +// args := &ThresholdsArgsProcessEvent{ +// ThresholdIDs: []string{"TH3"}, +// CGREvent: &utils.CGREvent{ +// Tenant: "cgrates.org", +// ID: "ThdProcessEvent", +// Event: map[string]interface{}{ +// utils.AccountField: "1001", +// }, +// }, +// } + +// expLog1 := `[WARNING] failed removing from database non-recurrent threshold: cgrates.org:TH3, error: NO_DATABASE_CONNECTION` +// expLog2 := `[WARNING] failed removing from cache non-recurrent threshold: cgrates.org:TH3, error: NO_DATABASE_CONNECTION` + +// if _, err := tS.processEvent(context.Background(), args.Tenant, args); err == nil || +// err != utils.ErrPartiallyExecuted { +// t.Errorf("expected: <%+v>, \nreceived: <%+v>", +// utils.ErrPartiallyExecuted, err) +// } + +// if rcvLog := buf.String(); !strings.Contains(rcvLog, expLog1) || +// !strings.Contains(rcvLog, expLog2) { +// t.Errorf("expected logs <%+v> and <%+v> to be included in: <%+v>", +// expLog1, expLog2, rcvLog) +// } + +// utils.Logger.SetLogLevel(0) +// } + +func TestThresholdsProcessEventNotFound(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + filterS := NewFilterS(cfg, nil, dm) + tS := NewThresholdService(dm, cfg, filterS, nil) + + thPrf := &ThresholdProfile{ + Tenant: "cgrates.org", + ID: "TH5", + FilterIDs: []string{"*string:~*req.Account:1001"}, + MinHits: 2, + MaxHits: 5, + Weight: 10, + Blocker: true, + } + th := &Threshold{ + Tenant: "cgrates.org", + ID: "TH5", + Hits: 2, + tPrfl: thPrf, + } + + if err := dm.SetThresholdProfile(context.Background(), thPrf, true); err != nil { + t.Error(err) + } + if err := dm.SetThreshold(context.Background(), th); err != nil { + t.Error(err) + } + + args := &ThresholdsArgsProcessEvent{ + ThresholdIDs: []string{"TH6"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "ThdProcessEvent", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + } + + if _, err := tS.processEvent(context.Background(), args.Tenant, args); err == nil || + err != utils.ErrNotFound { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) + } + +} + +// func TestThresholdsV1ProcessEventOK(t *testing.T) { +// tmp := Cache +// defer func() { +// Cache = tmp +// }() + +// cfg := config.NewDefaultCGRConfig() +// data := NewInternalDB(nil, nil, true) +// dm := NewDataManager(data, cfg.CacheCfg(), nil) +// Cache = NewCacheS(cfg, dm, nil) +// filterS := NewFilterS(cfg, nil, dm) +// tS := NewThresholdService(dm, cfg, filterS, nil) + +// thPrf1 := &ThresholdProfile{ +// Tenant: "cgrates.org", +// ID: "TH1", +// FilterIDs: []string{"*string:~*req.Account:1001"}, +// MinHits: 2, +// MaxHits: 5, +// Weight: 10, +// Blocker: true, +// } +// if err := dm.SetThresholdProfile(context.Background(), thPrf1, true); err != nil { +// t.Error(err) +// } + +// thPrf2 := &ThresholdProfile{ +// Tenant: "cgrates.org", +// ID: "TH2", +// FilterIDs: []string{"*string:~*req.Account:1001"}, +// MinHits: 0, +// MaxHits: 7, +// Weight: 20, +// Blocker: false, +// } +// if err := dm.SetThresholdProfile(context.Background(), thPrf2, true); err != nil { +// t.Error(err) +// } + +// args := &ThresholdsArgsProcessEvent{ +// CGREvent: &utils.CGREvent{ +// ID: "V1ProcessEventTest", +// Event: map[string]interface{}{ +// utils.AccountField: "1001", +// }, +// }, +// } +// var reply []string +// exp := []string{"TH1", "TH2"} +// if err := tS.V1ProcessEvent(context.Background(), args, &reply); err != nil { +// t.Error(err) +// } else { +// sort.Strings(reply) +// if !reflect.DeepEqual(reply, exp) { +// t.Errorf("expected: <%+v>, \nreceived: <%+v>", exp, reply) +// } +// } +// } + +// func TestThresholdsV1ProcessEventPartExecErr(t *testing.T) { +// tmp := Cache +// defer func() { +// Cache = tmp +// }() + +// utils.Logger.SetLogLevel(4) +// utils.Logger.SetSyslog(nil) + +// var buf bytes.Buffer +// log.SetOutput(&buf) +// defer func() { +// log.SetOutput(os.Stderr) +// }() + +// cfg := config.NewDefaultCGRConfig() +// data := NewInternalDB(nil, nil, true) +// dm := NewDataManager(data, cfg.CacheCfg(), nil) +// Cache = NewCacheS(cfg, dm, nil) +// filterS := NewFilterS(cfg, nil, dm) +// tS := NewThresholdService(dm, cfg, filterS, nil) + +// thPrf1 := &ThresholdProfile{ +// Tenant: "cgrates.org", +// ID: "TH3", +// FilterIDs: []string{"*string:~*req.Account:1001"}, +// MinHits: 2, +// MaxHits: 5, +// Weight: 10, +// Blocker: true, +// } +// if err := dm.SetThresholdProfile(context.Background(), thPrf1, true); err != nil { +// t.Error(err) +// } + +// thPrf2 := &ThresholdProfile{ +// Tenant: "cgrates.org", +// ID: "TH4", +// FilterIDs: []string{"*string:~*req.Account:1001"}, +// MinHits: 0, +// MaxHits: 7, +// Weight: 20, +// Blocker: false, +// } +// if err := dm.SetThresholdProfile(context.Background(), thPrf2, true); err != nil { +// t.Error(err) +// } + +// args := &ThresholdsArgsProcessEvent{ +// CGREvent: &utils.CGREvent{ +// ID: "V1ProcessEventTest", +// Event: map[string]interface{}{ +// utils.AccountField: "1001", +// }, +// }, +// } +// expLog1 := `[ERROR] Failed to get actions for ACT1: NOT_FOUND` +// expLog2 := `[WARNING] failed executing actions: ACT1, error: NOT_FOUND` +// var reply []string +// if err := tS.V1ProcessEvent(context.Background(), args, &reply); err == nil || +// err != utils.ErrPartiallyExecuted { +// t.Errorf("expected: <%+v>,\nreceived: <%+v>", utils.ErrPartiallyExecuted, err) +// } else { +// if rcvLog := buf.String(); !strings.Contains(rcvLog, expLog1) || +// !strings.Contains(rcvLog, expLog2) { +// t.Errorf("expected logs <%+v> and <%+v> to be included in: <%+v>", +// expLog1, expLog2, rcvLog) +// } +// } + +// utils.Logger.SetLogLevel(0) +// } + +func TestThresholdsV1ProcessEventMissingArgs(t *testing.T) { + tmp := Cache + defer func() { + Cache = tmp + }() + + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + Cache = NewCacheS(cfg, dm, nil) + filterS := NewFilterS(cfg, nil, dm) + tS := NewThresholdService(dm, cfg, filterS, nil) + + thPrf1 := &ThresholdProfile{ + Tenant: "cgrates.org", + ID: "TH1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + MinHits: 2, + MaxHits: 5, + Weight: 10, + Blocker: true, + } + if err := dm.SetThresholdProfile(context.Background(), thPrf1, true); err != nil { + t.Error(err) + } + + thPrf2 := &ThresholdProfile{ + Tenant: "cgrates.org", + ID: "TH2", + FilterIDs: []string{"*string:~*req.Account:1001"}, + MinHits: 0, + MaxHits: 7, + Weight: 20, + Blocker: false, + } + if err := dm.SetThresholdProfile(context.Background(), thPrf2, true); err != nil { + t.Error(err) + } + + args := &ThresholdsArgsProcessEvent{ + CGREvent: &utils.CGREvent{ + ID: "V1ProcessEventTest", + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + } + + args = &ThresholdsArgsProcessEvent{ + CGREvent: &utils.CGREvent{ + Event: map[string]interface{}{ + utils.AccountField: "1001", + }, + }, + } + var reply []string + experr := `MANDATORY_IE_MISSING: [ID]` + if err := tS.V1ProcessEvent(context.Background(), args, &reply); err == nil || + err.Error() != experr { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) + } + + args = &ThresholdsArgsProcessEvent{ + CGREvent: nil, + } + experr = `MANDATORY_IE_MISSING: [CGREvent]` + if err := tS.V1ProcessEvent(context.Background(), args, &reply); err == nil || + err.Error() != experr { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) + } + + args = &ThresholdsArgsProcessEvent{ + CGREvent: &utils.CGREvent{ + ID: "V1ProcessEventTest", + Event: nil, + }, + } + experr = `MANDATORY_IE_MISSING: [Event]` + if err := tS.V1ProcessEvent(context.Background(), args, &reply); err == nil || + err.Error() != experr { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", experr, err) + } +} + +func TestThresholdsV1GetThresholdOK(t *testing.T) { + tmp := Cache + defer func() { + Cache = tmp + }() + + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + Cache = NewCacheS(cfg, dm, nil) + filterS := NewFilterS(cfg, nil, dm) + tS := NewThresholdService(dm, cfg, filterS, nil) + + thPrf := &ThresholdProfile{ + Tenant: "cgrates.org", + ID: "TH1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + MinHits: 2, + MaxHits: 5, + Weight: 10, + Blocker: true, + } + if err := dm.SetThresholdProfile(context.Background(), thPrf, true); err != nil { + t.Error(err) + } + + expTh := Threshold{ + Tenant: "cgrates.org", + ID: "TH1", + Hits: 0, + } + var rplyTh Threshold + if err := tS.V1GetThreshold(context.Background(), &utils.TenantID{ + ID: "TH1", + }, &rplyTh); err != nil { + t.Error(err) + } else { + var snooze time.Time + rplyTh.dirty = nil + rplyTh.Snooze = snooze + if !reflect.DeepEqual(rplyTh, expTh) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(expTh), utils.ToJSON(rplyTh)) + } + } +} + +func TestThresholdsV1GetThresholdNotFoundErr(t *testing.T) { + tmp := Cache + defer func() { + Cache = tmp + }() + + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, true) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + Cache = NewCacheS(cfg, dm, nil) + filterS := NewFilterS(cfg, nil, dm) + tS := NewThresholdService(dm, cfg, filterS, nil) + + thPrf := &ThresholdProfile{ + Tenant: "cgrates.org", + ID: "TH1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + MinHits: 2, + MaxHits: 5, + Weight: 10, + Blocker: true, + } + if err := dm.SetThresholdProfile(context.Background(), thPrf, true); err != nil { + t.Error(err) + } + + var rplyTh Threshold + if err := tS.V1GetThreshold(context.Background(), &utils.TenantID{ + ID: "TH2", + }, &rplyTh); err == nil || err != utils.ErrNotFound { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) + } +}