diff --git a/apier/v1/apier_it_test.go b/apier/v1/apier_it_test.go index c0bbf1141..ab7144d63 100644 --- a/apier/v1/apier_it_test.go +++ b/apier/v1/apier_it_test.go @@ -698,7 +698,7 @@ func TestApierLoadAccountActions(t *testing.T) { if err := rater.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil { t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) } else if !reflect.DeepEqual(expectedStats, rcvStats) { - t.Errorf("Calling ApierV1.GetCacheStats expected: %+v, received: %+v", expectedStats, rcvStats) + t.Errorf("Calling ApierV1.GetCacheStats expected: %+v, received: %+v", utils.ToJSON(expectedStats), utils.ToJSON(rcvStats)) } } diff --git a/apier/v1/cdre_it_test.go b/apier/v1/cdre_it_test.go index 4f0032cc4..fce76fdb4 100755 --- a/apier/v1/cdre_it_test.go +++ b/apier/v1/cdre_it_test.go @@ -24,6 +24,7 @@ import ( "net/rpc" "net/rpc/jsonrpc" "path" + "reflect" "testing" "time" @@ -49,6 +50,8 @@ var sTestsCDRE = []func(t *testing.T){ testCDReRPCConn, testCDReAddCDRs, testCDReExportCDRs, + testCDReFromFolder, + testCDReProcessExternalCdr, testCDReKillEngine, } @@ -156,6 +159,93 @@ func testCDReExportCDRs(t *testing.T) { } } +func testCDReFromFolder(t *testing.T) { + var reply string + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} + if err := cdreRPC.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { + t.Error(err) + } + time.Sleep(500 * time.Millisecond) +} + +// Test CDR from external sources +func testCDReProcessExternalCdr(t *testing.T) { + cdr := &engine.ExternalCDR{ToR: utils.VOICE, + OriginID: "testextcdr1", OriginHost: "127.0.0.1", Source: utils.UNIT_TEST, RequestType: utils.META_RATED, + Tenant: "cgrates.org", Category: "call", Account: "1003", Subject: "1003", Destination: "1001", + SetupTime: "2014-08-04T13:00:00Z", AnswerTime: "2014-08-04T13:00:07Z", + Usage: "1s", ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + } + var reply string + if err := cdreRPC.Call("CdrsV1.ProcessExternalCdr", cdr, &reply); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if reply != utils.OK { + t.Error("Unexpected reply received: ", reply) + } + time.Sleep(50 * time.Millisecond) + var cdrs []*engine.ExternalCDR + args := utils.RPCCDRsFilter{OriginIDs: []string{"testextcdr1"}} + if err := cdreRPC.Call("ApierV2.GetCdrs", args, &cdrs); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(cdrs) != 2 { + t.Errorf("Unexpected number of CDRs returned: %v, cdrs=%s ", len(cdrs), utils.ToJSON(cdrs)) + return + } else { + for _, c := range cdrs { + if c.RunID == utils.MetaRaw && c.Cost != -1 { + t.Errorf("Expected for *raw cdr cost to be -1, recived: %v", c.Cost) + } + if c.RunID == utils.MetaDefault && c.Cost != 0.3 { + t.Errorf("Expected for *default cdr cost to be 0.3, recived: %v", c.Cost) + } + if c.RunID == utils.MetaDefault { + acdr, err := engine.NewCDRFromExternalCDR(c, "") + if err != nil { + t.Error(err) + return + } + if acdr.CostDetails == nil { + t.Errorf("CostDetails should not be nil") + return + } + if acdr.CostDetails.Usage == nil { + t.Errorf("CostDetails for procesed cdr has usage nil") + } + if acdr.CostDetails.Cost == nil { + t.Errorf("CostDetails for procesed cdr has cost nil") + } + } + if c.Usage != "1s" { + t.Errorf("Expected 1s,recived %s", c.Usage) + } + if c.Source != utils.UNIT_TEST { + t.Errorf("Expected %s,recived %s", utils.UNIT_TEST, c.Source) + } + if c.ToR != utils.VOICE { + t.Errorf("Expected %s,recived %s", utils.VOICE, c.ToR) + } + if c.RequestType != utils.META_RATED { + t.Errorf("Expected %s,recived %s", utils.META_RATED, c.RequestType) + } + if c.Category != "call" { + t.Errorf("Expected call,recived %s", c.Category) + } + if c.Account != "1003" { + t.Errorf("Expected 1003,recived %s", c.Account) + } + if c.Subject != "1003" { + t.Errorf("Expected 1003,recived %s", c.Subject) + } + if c.Destination != "1001" { + t.Errorf("Expected 1001,recived %s", c.Destination) + } + if !reflect.DeepEqual(c.ExtraFields, cdr.ExtraFields) { + t.Errorf("Expected %s,recived %s", utils.ToJSON(c.ExtraFields), utils.ToJSON(cdr.ExtraFields)) + } + } + } +} + func testCDReKillEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) diff --git a/apier/v1/stats_it_test.go b/apier/v1/stats_it_test.go index c207ab68b..5b9676040 100644 --- a/apier/v1/stats_it_test.go +++ b/apier/v1/stats_it_test.go @@ -393,13 +393,12 @@ func testV1STSUpdateStatQueueProfile(t *testing.T) { } else if result != utils.OK { t.Error("Unexpected reply returned", result) } - time.Sleep(time.Second) var reply *engine.StatQueueProfile if err := stsV1Rpc.Call("ApierV1.GetStatQueueProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &reply); err != nil { t.Error(err) } else if !reflect.DeepEqual(statConfig, reply) { - t.Errorf("Expecting: %+v, received: %+v", statConfig, reply) + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(statConfig), utils.ToJSON(reply)) } } @@ -411,6 +410,9 @@ func testV1STSRemoveStatQueueProfile(t *testing.T) { } else if resp != utils.OK { t.Error("Unexpected reply returned", resp) } + if tSv1ConfDIR == "tutmongo" { + time.Sleep(150 * time.Millisecond) + } var sqp *engine.StatQueueProfile if err := stsV1Rpc.Call("ApierV1.GetStatQueueProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &sqp); err == nil || err.Error() != utils.ErrNotFound.Error() { diff --git a/engine/cdr.go b/engine/cdr.go index 251c5fcb7..b8435625b 100644 --- a/engine/cdr.go +++ b/engine/cdr.go @@ -55,6 +55,7 @@ func NewCDRFromExternalCDR(extCdr *ExternalCDR, timezone string) (*CDR, error) { } } if len(extCdr.CostDetails) != 0 { + cdr.CostDetails = &EventCost{} if err = json.Unmarshal([]byte(extCdr.CostDetails), cdr.CostDetails); err != nil { return nil, err } diff --git a/engine/cdrs.go b/engine/cdrs.go index 66b5515ca..2cbbe8e42 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -283,6 +283,9 @@ func (self *CdrServer) deriveRateStoreStatsReplicate(cdr *CDR, store, cdrstats, // Store rated CDRs if store { for _, ratedCDR := range ratedCDRs { + if ratedCDR.CostDetails != nil { + ratedCDR.CostDetails.Compute() + } if err := self.cdrDb.SetCDR(ratedCDR, true); err != nil { utils.Logger.Err(fmt.Sprintf(" Storing rated CDR %+v, got error: %s", ratedCDR, err.Error())) }