From 33b3cbbcd1ebec4b83a087794d669ac5c4f5f6e7 Mon Sep 17 00:00:00 2001 From: DanB Date: Sat, 21 Nov 2015 12:09:31 +0100 Subject: [PATCH] Tests for re-rating --- agents/libdmt.go | 13 ++++++ apier/v2/cdrs_mysql_local_test.go | 69 ++++++++++++++++++++++++++++++- apier/v2/cdrs_psql_local_test.go | 69 ++++++++++++++++++++++++++++++- engine/cdrs.go | 3 ++ 4 files changed, 150 insertions(+), 4 deletions(-) diff --git a/agents/libdmt.go b/agents/libdmt.go index 3346b97df..bcc861e51 100644 --- a/agents/libdmt.go +++ b/agents/libdmt.go @@ -28,6 +28,7 @@ import ( "strconv" "time" + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" "github.com/fiorix/go-diameter/diam" "github.com/fiorix/go-diameter/diam/avp" @@ -120,3 +121,15 @@ func storedCdrToCCR(cdr *engine.StoredCdr, originHost, originRealm string, vendo */ return m } + +// Extracts the value out of a specific field in diameter message, able to go into multiple layers in the form of field1>field2>field3 +func dmtMessageFieldValue(dm *diam.Message, fieldId string) string { + //fieldNameLevels := strings.Split(fieldId, ">") + return "" + +} + +// Converts Diameter CCR message into StoredCdr based on field template +func ccrToStoredCdr(ccr *diam.Message, tpl []*config.CfgCdrField) (*engine.StoredCdr, error) { + return nil, nil +} diff --git a/apier/v2/cdrs_mysql_local_test.go b/apier/v2/cdrs_mysql_local_test.go index de3049542..5b5444973 100644 --- a/apier/v2/cdrs_mysql_local_test.go +++ b/apier/v2/cdrs_mysql_local_test.go @@ -79,10 +79,10 @@ func TestV2CdrsMysqlInjectUnratedCdr(t *testing.T) { t.Error("Error on opening database connection: ", err) return } - strCdr1 := &engine.StoredCdr{CgrId: utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), + strCdr1 := &engine.StoredCdr{CgrId: utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()), TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), + SetupTime: time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC), AnswerTime: time.Date(2015, 11, 21, 10, 47, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} if err := mysqlDb.SetCdr(strCdr1); err != nil { @@ -239,6 +239,71 @@ func TestV2CdrsMysqlProcessPrepaidCdr(t *testing.T) { } } +func TestV2CdrsMysqlRateWithoutTP(t *testing.T) { + if !*testLocal { + return + } + rawCdrCgrId := utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()) + // Rate the injected CDR, should not rate it since we have no TP loaded + attrs := utils.AttrRateCdrs{CgrIds: []string{rawCdrCgrId}} + var reply string + if err := cdrsRpc.Call("CdrsV2.RateCdrs", attrs, &reply); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if reply != utils.OK { + t.Error("Unexpected reply received: ", reply) + } + var cdrs []*engine.ExternalCdr + req := utils.RpcCdrsFilter{CgrIds: []string{rawCdrCgrId}} + if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(cdrs) != 1 { + t.Error("Unexpected number of CDRs returned: ", len(reply)) + } else { + if cdrs[0].Cost != -1 { + t.Errorf("Unexpected CDR returned: %+v", cdrs[0]) + } + } +} + +func TestV2CdrsMysqloadTariffPlanFromFolder(t *testing.T) { + if !*testLocal { + return + } + var loadInst engine.LoadInstance + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} + if err := cdrsRpc.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &loadInst); err != nil { + t.Error(err) + } else if loadInst.LoadId == "" { + t.Error("Empty loadId received, loadInstance: ", loadInst) + } + time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups +} + +func TestV2CdrsMysqlRateWithTP(t *testing.T) { + if !*testLocal { + return + } + rawCdrCgrId := utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()) + attrs := utils.AttrRateCdrs{CgrIds: []string{rawCdrCgrId}} + var reply string + if err := cdrsRpc.Call("CdrsV2.RateCdrs", attrs, &reply); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if reply != utils.OK { + t.Error("Unexpected reply received: ", reply) + } + var cdrs []*engine.ExternalCdr + req := utils.RpcCdrsFilter{CgrIds: []string{rawCdrCgrId}} + if err := cdrsRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(cdrs) != 1 { + t.Error("Unexpected number of CDRs returned: ", len(reply)) + } else { + if cdrs[0].Cost != 0.3 { + t.Errorf("Unexpected CDR returned: %+v", cdrs[0]) + } + } +} + func TestV2CdrsMysqlKillEngine(t *testing.T) { if !*testLocal { return diff --git a/apier/v2/cdrs_psql_local_test.go b/apier/v2/cdrs_psql_local_test.go index 821a406ed..be4897115 100644 --- a/apier/v2/cdrs_psql_local_test.go +++ b/apier/v2/cdrs_psql_local_test.go @@ -76,10 +76,10 @@ func TestV2CdrsPsqlInjectUnratedCdr(t *testing.T) { t.Error("Error on opening database connection: ", err) return } - strCdr1 := &engine.StoredCdr{CgrId: utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), + strCdr1 := &engine.StoredCdr{CgrId: utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()), TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: utils.META_RATED, Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), + SetupTime: time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC), AnswerTime: time.Date(2015, 11, 21, 10, 47, 26, 0, time.UTC), Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} if err := psqlDb.SetCdr(strCdr1); err != nil { @@ -237,6 +237,71 @@ func TestV2CdrsPsqlProcessPrepaidCdr(t *testing.T) { } } +func TestV2CdrsPsqlRateWithoutTP(t *testing.T) { + if !*testLocal { + return + } + rawCdrCgrId := utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()) + // Rate the injected CDR, should not rate it since we have no TP loaded + attrs := utils.AttrRateCdrs{CgrIds: []string{rawCdrCgrId}} + var reply string + if err := cdrsPsqlRpc.Call("CdrsV2.RateCdrs", attrs, &reply); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if reply != utils.OK { + t.Error("Unexpected reply received: ", reply) + } + var cdrs []*engine.ExternalCdr + req := utils.RpcCdrsFilter{CgrIds: []string{rawCdrCgrId}} + if err := cdrsPsqlRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(cdrs) != 1 { + t.Error("Unexpected number of CDRs returned: ", len(reply)) + } else { + if cdrs[0].Cost != -1 { + t.Errorf("Unexpected CDR returned: %+v", cdrs[0]) + } + } +} + +func TestV2CdrsPsqlLoadTariffPlanFromFolder(t *testing.T) { + if !*testLocal { + return + } + var loadInst engine.LoadInstance + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} + if err := cdrsPsqlRpc.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &loadInst); err != nil { + t.Error(err) + } else if loadInst.LoadId == "" { + t.Error("Empty loadId received, loadInstance: ", loadInst) + } + time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups +} + +func TestV2CdrsPsqlRateWithTP(t *testing.T) { + if !*testLocal { + return + } + rawCdrCgrId := utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()) + attrs := utils.AttrRateCdrs{CgrIds: []string{rawCdrCgrId}} + var reply string + if err := cdrsPsqlRpc.Call("CdrsV2.RateCdrs", attrs, &reply); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if reply != utils.OK { + t.Error("Unexpected reply received: ", reply) + } + var cdrs []*engine.ExternalCdr + req := utils.RpcCdrsFilter{CgrIds: []string{rawCdrCgrId}} + if err := cdrsPsqlRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(cdrs) != 1 { + t.Error("Unexpected number of CDRs returned: ", len(reply)) + } else { + if cdrs[0].Cost != 0.3 { + t.Errorf("Unexpected CDR returned: %+v", cdrs[0]) + } + } +} + func TestV2CdrsPsqlKillEngine(t *testing.T) { if !*testLocal { return diff --git a/engine/cdrs.go b/engine/cdrs.go index b9316a84c..ae246729e 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -143,6 +143,9 @@ func (self *CdrServer) RateCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqT return err } for _, cdr := range cdrs { + if cdr.MediationRunId == "" { // raw CDRs which were not calculated before + cdr.MediationRunId = utils.META_DEFAULT + } if err := self.rateStoreStatsReplicate(cdr); err != nil { utils.Logger.Err(fmt.Sprintf(" Processing CDR %+v, got error: %s", cdr, err.Error())) }