diff --git a/engine/attributes_test.go b/engine/attributes_test.go index b2f2c2fca..039f39010 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -1365,11 +1365,24 @@ func TestAttributesParseAttributeSIPCIDInvalidArguments(t *testing.T) { // }, // } // reply := &AttrSProcessEventReply{} +// exp := &AttrSProcessEventReply{ +// MatchedProfiles: []string{"cgrates.org:ATTR1", "cgrates.org:ATTR2"}, +// AlteredFields: []string{"*req.Password", "*req.RequestType"}, +// CGREvent: &utils.CGREvent{ +// Tenant: "cgrates.org", +// ID: "AttrProcessEventMultipleRuns", +// Event: map[string]interface{}{ +// utils.Password: "CGRateS.org", +// utils.RequestType: utils.MetaPostpaid, +// }, +// }, +// } // if err := alS.V1ProcessEvent(args, reply); err != nil { // t.Error(err) +// } else if !reflect.DeepEqual(reply, exp) { +// t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(exp), utils.ToJSON(reply)) // } -// fmt.Println(utils.ToJSON(reply)) // } // func TestAttributesV1ProcessEventMultipleRuns2(t *testing.T) { @@ -1455,10 +1468,25 @@ func TestAttributesParseAttributeSIPCIDInvalidArguments(t *testing.T) { // Event: map[string]interface{}{}, // }, // } -// reply := &AttrSProcessEventReply{} +// reply := &AttrSProcessEventReply{} +// exp := &AttrSProcessEventReply{ +// MatchedProfiles: []string{"cgrates.org:ATTR1", "cgrates.org:ATTR2", "cgrates.org:ATTR3"}, +// AlteredFields: []string{"*req.Password", "*req.RequestType", "*req.PaypalAccount"}, +// CGREvent: &utils.CGREvent{ +// Tenant: "cgrates.org", +// ID: "AttrProcessEventMultipleRuns", +// Event: map[string]interface{}{ +// utils.Password: "CGRateS.org", +// "PaypalAccount": "cgrates@paypal.com", +// utils.RequestType: utils.MetaPostpaid, +// }, +// }, +// } // if err := alS.V1ProcessEvent(args, reply); err != nil { // t.Error(err) +// } else if !reflect.DeepEqual(reply, exp) { +// t.Errorf("expected: <%+v>, \nreceived: <%+v>", +// utils.ToJSON(exp), utils.ToJSON(reply)) // } -// fmt.Println(utils.ToJSON(reply)) // } diff --git a/engine/thresholds_test.go b/engine/thresholds_test.go index d08609243..a9ad1e77e 100644 --- a/engine/thresholds_test.go +++ b/engine/thresholds_test.go @@ -22,6 +22,7 @@ import ( "log" "os" "reflect" + "sort" "strings" "testing" "time" @@ -1782,3 +1783,301 @@ func TestThresholdsProcessEventNotFound(t *testing.T) { } } + +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) + + 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(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(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(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) + + 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(thPrf1, true); err != nil { + t.Error(err) + } + + thPrf2 := &ThresholdProfile{ + Tenant: "cgrates.org", + ID: "TH4", + FilterIDs: []string{"*string:~*req.Account:1001"}, + ActionIDs: []string{"ACT1"}, + MinHits: 0, + MaxHits: 7, + Weight: 20, + Blocker: false, + } + if err := dm.SetThresholdProfile(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(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) + + 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(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(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(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(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(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) + + 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(thPrf, true); err != nil { + t.Error(err) + } + + expTh := Threshold{ + Tenant: "cgrates.org", + ID: "TH1", + Hits: 0, + } + var rplyTh Threshold + if err := tS.V1GetThreshold(&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) + + 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(thPrf, true); err != nil { + t.Error(err) + } + + var rplyTh Threshold + if err := tS.V1GetThreshold(&utils.TenantID{ + ID: "TH2", + }, &rplyTh); err == nil || err != utils.ErrNotFound { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) + } +}