mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-17 06:09:53 +05:00
Synched FSCDR with FSCdr object + coeverage tests
This commit is contained in:
committed by
Dan Christian Bogos
parent
eb39a5ffff
commit
84c8cf038c
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package agents
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -953,15 +954,20 @@ variable_rtp_audio_rtcp_octet_count: 0`
|
||||
var fsCdrCfg *config.CGRConfig
|
||||
timezone := config.CgrConfig().GeneralCfg().DefaultTimezone
|
||||
fsCdrCfg, _ = config.NewDefaultCGRConfig()
|
||||
fsCdr, _ := engine.NewFSCdr(body, fsCdrCfg)
|
||||
newReader := bytes.NewReader(body)
|
||||
fsCdr, err := engine.NewFSCdr(newReader, fsCdrCfg)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
smGev := engine.NewMapEvent(NewFSEvent(hangUp).AsMapStringInterface(timezone))
|
||||
sessions.GetSetCGRID(smGev)
|
||||
smCDR, err := smGev.AsCDR(fsCdrCfg, utils.EmptyString, timezone)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fsCDR := fsCdr.AsCDR(timezone)
|
||||
if fsCDR.CGRID != smCDR.CGRID {
|
||||
if fsCDR, err := fsCdr.AsCDR(timezone); err != nil {
|
||||
t.Error(err)
|
||||
} else if fsCDR.CGRID != smCDR.CGRID {
|
||||
t.Errorf("Expecting: %s, received: %s", fsCDR.CGRID, smCDR.CGRID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -29,10 +28,8 @@ import (
|
||||
"github.com/cgrates/rpcclient"
|
||||
)
|
||||
|
||||
var cdrServer *CDRServer // Share the server so we can use it in http handlers
|
||||
|
||||
// cgrCdrHandler handles CDRs received over HTTP REST
|
||||
func cgrCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||
func (cdrS *CDRServer) cgrCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||
cgrCdr, err := NewCgrCdrFromHttpReq(r)
|
||||
if err != nil {
|
||||
utils.Logger.Warning(
|
||||
@@ -40,7 +37,7 @@ func cgrCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||
utils.CDRs, r.Form, err.Error()))
|
||||
return
|
||||
}
|
||||
cdr, err := cgrCdr.AsCDR(cdrServer.cgrCfg.GeneralCfg().DefaultTimezone)
|
||||
cdr, err := cgrCdr.AsCDR(cdrS.cgrCfg.GeneralCfg().DefaultTimezone)
|
||||
if err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> could not create CDR entry from rawCDR: %+v, err <%s>",
|
||||
@@ -48,7 +45,7 @@ func cgrCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
var ignored string
|
||||
if err := cdrServer.V1ProcessCDR(&CDRWithOpts{CDR: cdr}, &ignored); err != nil {
|
||||
if err := cdrS.V1ProcessCDR(&CDRWithOpts{CDR: cdr}, &ignored); err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> processing CDR: %s, err: <%s>",
|
||||
utils.CDRs, cdr, err.Error()))
|
||||
@@ -56,16 +53,20 @@ func cgrCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// fsCdrHandler will handle CDRs received from FreeSWITCH over HTTP-JSON
|
||||
func fsCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
fsCdr, err := NewFSCdr(body, cdrServer.cgrCfg)
|
||||
func (cdrS *CDRServer) fsCdrHandler(w http.ResponseWriter, r *http.Request) {
|
||||
fsCdr, err := NewFSCdr(r.Body, cdrS.cgrCfg)
|
||||
r.Body.Close()
|
||||
if err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<CDRS> Could not create CDR entry: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
cdr := fsCdr.AsCDR(cdrServer.cgrCfg.GeneralCfg().DefaultTimezone)
|
||||
cdr, err := fsCdr.AsCDR(cdrS.cgrCfg.GeneralCfg().DefaultTimezone)
|
||||
if err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<CDRS> Could not create AsCDR entry: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
var ignored string
|
||||
if err := cdrServer.V1ProcessCDR(&CDRWithOpts{CDR: cdr}, &ignored); err != nil {
|
||||
if err := cdrS.V1ProcessCDR(&CDRWithOpts{CDR: cdr}, &ignored); err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> processing CDR: %s, err: <%s>",
|
||||
utils.CDRs, cdr, err.Error()))
|
||||
@@ -115,9 +116,8 @@ func (cdrS *CDRServer) ListenAndServe(stopChan chan struct{}) (err error) {
|
||||
|
||||
// RegisterHandlersToServer is called by cgr-engine to register HTTP URL handlers
|
||||
func (cdrS *CDRServer) RegisterHandlersToServer(server *utils.Server) {
|
||||
cdrServer = cdrS // Share the server object for handlers
|
||||
server.RegisterHttpFunc(cdrS.cgrCfg.HTTPCfg().HTTPCDRsURL, cgrCdrHandler)
|
||||
server.RegisterHttpFunc(cdrS.cgrCfg.HTTPCfg().HTTPFreeswitchCDRsURL, fsCdrHandler)
|
||||
server.RegisterHttpFunc(cdrS.cgrCfg.HTTPCfg().HTTPCDRsURL, cdrS.cgrCdrHandler)
|
||||
server.RegisterHttpFunc(cdrS.cgrCfg.HTTPCfg().HTTPFreeswitchCDRsURL, cdrS.fsCdrHandler)
|
||||
}
|
||||
|
||||
// storeSMCost will store a SMCost
|
||||
|
||||
@@ -21,6 +21,7 @@ package engine
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -48,20 +49,20 @@ const (
|
||||
FsIPv4 = "FreeSWITCH-IPv4"
|
||||
)
|
||||
|
||||
func NewFSCdr(body []byte, cgrCfg *config.CGRConfig) (*FSCdr, error) {
|
||||
func NewFSCdr(body io.Reader, cgrCfg *config.CGRConfig) (*FSCdr, error) {
|
||||
fsCdr := &FSCdr{cgrCfg: cgrCfg, vars: make(map[string]string)}
|
||||
var err error
|
||||
if err = json.Unmarshal(body, &fsCdr.body); err == nil {
|
||||
if variables, ok := fsCdr.body[FS_CDR_MAP]; ok {
|
||||
if variables, ok := variables.(map[string]interface{}); ok {
|
||||
for k, v := range variables {
|
||||
fsCdr.vars[k] = v.(string)
|
||||
}
|
||||
if err = json.NewDecoder(body).Decode(&fsCdr.body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if variables, ok := fsCdr.body[FS_CDR_MAP]; ok {
|
||||
if variables, ok := variables.(map[string]interface{}); ok {
|
||||
for k, v := range variables {
|
||||
fsCdr.vars[k] = v.(string)
|
||||
}
|
||||
return fsCdr, nil
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
return fsCdr, nil
|
||||
}
|
||||
|
||||
type FSCdr struct {
|
||||
@@ -88,7 +89,6 @@ func (fsCdr FSCdr) getExtraFields() map[string]string {
|
||||
if parsed, err := field.Parse(origFieldVal); err == nil {
|
||||
extraFields[field.Id] = parsed
|
||||
}
|
||||
|
||||
}
|
||||
return extraFields
|
||||
}
|
||||
@@ -136,32 +136,54 @@ func (fsCdr FSCdr) firstDefined(fldNames []string, dfltFld string) (val string)
|
||||
return fsCdr.searchExtraField(dfltFld, fsCdr.body)
|
||||
}
|
||||
|
||||
func (fsCdr FSCdr) AsCDR(timezone string) *CDR {
|
||||
storCdr := new(CDR)
|
||||
storCdr.CGRID = fsCdr.getCGRID()
|
||||
storCdr.ToR = utils.VOICE
|
||||
storCdr.OriginID = fsCdr.vars[FS_UUID]
|
||||
storCdr.OriginHost = utils.FirstNonEmpty(fsCdr.vars[utils.CGROriginHost],
|
||||
fsCdr.vars[FsIPv4])
|
||||
storCdr.Source = FS_CDR_SOURCE
|
||||
storCdr.RequestType = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_REQTYPE],
|
||||
fsCdr.cgrCfg.GeneralCfg().DefaultReqType)
|
||||
storCdr.Tenant = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_TENANT],
|
||||
fsCdr.cgrCfg.GeneralCfg().DefaultTenant)
|
||||
storCdr.Category = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_CATEGORY],
|
||||
fsCdr.cgrCfg.GeneralCfg().DefaultCategory)
|
||||
storCdr.Account = fsCdr.firstDefined([]string{utils.CGR_ACCOUNT, FS_USERNAME},
|
||||
FsUsername)
|
||||
storCdr.Subject = fsCdr.firstDefined([]string{utils.CGR_SUBJECT,
|
||||
utils.CGR_ACCOUNT, FS_USERNAME}, FsUsername)
|
||||
storCdr.Destination = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_DESTINATION],
|
||||
fsCdr.vars[FS_CALL_DEST_NR], fsCdr.vars[FS_SIP_REQUSER])
|
||||
storCdr.SetupTime, _ = utils.ParseTimeDetectLayout(fsCdr.vars[FS_SETUP_TIME],
|
||||
timezone) // Not interested to process errors, should do them if necessary in a previous step
|
||||
storCdr.AnswerTime, _ = utils.ParseTimeDetectLayout(fsCdr.vars[FS_ANSWER_TIME],
|
||||
timezone)
|
||||
storCdr.Usage, _ = utils.ParseDurationWithSecs(fsCdr.vars[FS_DURATION])
|
||||
storCdr.ExtraFields = fsCdr.getExtraFields()
|
||||
storCdr.Cost = -1
|
||||
return storCdr
|
||||
func (fsCdr FSCdr) AsCDR(timezone string) (storCdr *CDR, err error) {
|
||||
storCdr = &CDR{
|
||||
CGRID: fsCdr.getCGRID(),
|
||||
RunID: fsCdr.vars["cgr_runid"],
|
||||
OriginHost: utils.FirstNonEmpty(fsCdr.vars[utils.CGROriginHost], fsCdr.vars[FsIPv4]),
|
||||
Source: FS_CDR_SOURCE,
|
||||
OriginID: fsCdr.vars[FS_UUID],
|
||||
ToR: utils.VOICE,
|
||||
RequestType: utils.FirstNonEmpty(fsCdr.vars[utils.CGR_REQTYPE], fsCdr.cgrCfg.GeneralCfg().DefaultReqType),
|
||||
Tenant: utils.FirstNonEmpty(fsCdr.vars[utils.CGR_TENANT], fsCdr.cgrCfg.GeneralCfg().DefaultTenant),
|
||||
Category: utils.FirstNonEmpty(fsCdr.vars[utils.CGR_CATEGORY], fsCdr.cgrCfg.GeneralCfg().DefaultCategory),
|
||||
Account: fsCdr.firstDefined([]string{utils.CGR_ACCOUNT, FS_USERNAME}, FsUsername),
|
||||
Subject: fsCdr.firstDefined([]string{utils.CGR_SUBJECT, utils.CGR_ACCOUNT, FS_USERNAME}, FsUsername),
|
||||
Destination: utils.FirstNonEmpty(fsCdr.vars[utils.CGR_DESTINATION], fsCdr.vars[FS_CALL_DEST_NR], fsCdr.vars[FS_SIP_REQUSER]),
|
||||
ExtraFields: fsCdr.getExtraFields(),
|
||||
ExtraInfo: fsCdr.vars["cgr_extrainfo"],
|
||||
CostSource: fsCdr.vars["cgr_costsource"],
|
||||
Cost: -1,
|
||||
}
|
||||
if orderId, hasIt := fsCdr.vars["cgr_orderid"]; hasIt {
|
||||
if storCdr.OrderID, err = strconv.ParseInt(orderId, 10, 64); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if setupTime, hasIt := fsCdr.vars[FS_SETUP_TIME]; hasIt {
|
||||
if storCdr.SetupTime, err = utils.ParseTimeDetectLayout(setupTime, timezone); err != nil {
|
||||
return nil, err
|
||||
} // Not interested to process errors, should do them if necessary in a previous step
|
||||
}
|
||||
if answerTime, hasIt := fsCdr.vars[FS_ANSWER_TIME]; hasIt {
|
||||
if storCdr.AnswerTime, err = utils.ParseTimeDetectLayout(answerTime, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if usage, hasIt := fsCdr.vars[FS_DURATION]; hasIt {
|
||||
if storCdr.Usage, err = utils.ParseDurationWithSecs(usage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if partial, hasIt := fsCdr.vars["cgr_partial"]; hasIt {
|
||||
if storCdr.Partial, err = strconv.ParseBool(partial); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if preRated, hasIt := fsCdr.vars["cgr_prerated"]; hasIt {
|
||||
if storCdr.PreRated, err = strconv.ParseBool(preRated); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -394,7 +395,8 @@ var fsCdrCfg *config.CGRConfig
|
||||
|
||||
func TestFsCdrFirstNonEmpty(t *testing.T) {
|
||||
fsCdrCfg, _ = config.NewDefaultCGRConfig()
|
||||
fsCdr, err := NewFSCdr(body, fsCdrCfg)
|
||||
reader := bytes.NewReader(body)
|
||||
fsCdr, err := NewFSCdr(reader, fsCdrCfg)
|
||||
if err != nil {
|
||||
t.Errorf("Error loading cdr: %v", err)
|
||||
}
|
||||
@@ -406,7 +408,8 @@ func TestFsCdrFirstNonEmpty(t *testing.T) {
|
||||
|
||||
func TestFsCdrCDRFields(t *testing.T) {
|
||||
fsCdrCfg.CdrsCfg().ExtraFields = []*utils.RSRField{{Id: "sip_user_agent"}}
|
||||
fsCdr, err := NewFSCdr(body, fsCdrCfg)
|
||||
reader := bytes.NewReader(body)
|
||||
fsCdr, err := NewFSCdr(reader, fsCdrCfg)
|
||||
if err != nil {
|
||||
t.Errorf("Error loading cdr: %v", err)
|
||||
}
|
||||
@@ -422,13 +425,19 @@ func TestFsCdrCDRFields(t *testing.T) {
|
||||
AnswerTime: answerTime, Usage: 68 * time.Second,
|
||||
Cost: -1,
|
||||
ExtraFields: map[string]string{"sip_user_agent": "Jitsi2.10.5550Linux"}}
|
||||
if CDR := fsCdr.AsCDR(""); !reflect.DeepEqual(expctCDR, CDR) {
|
||||
if CDR, err := fsCdr.AsCDR(""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expctCDR, CDR) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", expctCDR, CDR)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFsCdrSearchExtraFieldLast(t *testing.T) {
|
||||
fsCdr, _ := NewFSCdr(body, fsCdrCfg)
|
||||
newReader := bytes.NewReader(body)
|
||||
fsCdr, err := NewFSCdr(newReader, fsCdrCfg)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
value := fsCdr.searchExtraField("progress_media_time", fsCdr.body)
|
||||
if value != "1515666347954373" {
|
||||
t.Error("Error finding extra field: ", value)
|
||||
@@ -436,7 +445,11 @@ func TestFsCdrSearchExtraFieldLast(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFsCdrSearchExtraField(t *testing.T) {
|
||||
fsCdr, _ := NewFSCdr(body, fsCdrCfg)
|
||||
newReader := bytes.NewReader(body)
|
||||
fsCdr, err := NewFSCdr(newReader, fsCdrCfg)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
rsrSt1, _ := utils.NewRSRField("^injected_value")
|
||||
rsrSt2, _ := utils.NewRSRField("^injected_hdr::injected_value/")
|
||||
fsCdrCfg.CdrsCfg().ExtraFields = []*utils.RSRField{{Id: "caller_id_name"}, rsrSt1, rsrSt2}
|
||||
@@ -450,15 +463,21 @@ func TestFsCdrSearchExtraField(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFsCdrSearchExtraFieldInSlice(t *testing.T) {
|
||||
fsCdr, _ := NewFSCdr(body, fsCdrCfg)
|
||||
if value := fsCdr.searchExtraField("floatfld1", map[string]interface{}{"floatfld1": 6.4}); value != "6.4" {
|
||||
newReader := bytes.NewReader(body)
|
||||
if fsCdr, err := NewFSCdr(newReader, fsCdrCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else if value := fsCdr.searchExtraField("floatfld1", map[string]interface{}{"floatfld1": 6.4}); value != "6.4" {
|
||||
t.Errorf("Expecting: 6.4, received: %s", value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFsCdrSearchReplaceInExtraFields(t *testing.T) {
|
||||
fsCdrCfg.CdrsCfg().ExtraFields = utils.ParseRSRFieldsMustCompile(`read_codec;~sip_user_agent:s/([A-Za-z]*).+/$1/;write_codec`, utils.INFIELD_SEP)
|
||||
fsCdr, _ := NewFSCdr(body, fsCdrCfg)
|
||||
newReader := bytes.NewReader(body)
|
||||
fsCdr, err := NewFSCdr(newReader, fsCdrCfg)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
extraFields := fsCdr.getExtraFields()
|
||||
if len(extraFields) != 3 {
|
||||
t.Error("Error parsing extra fields: ", extraFields)
|
||||
@@ -509,7 +528,8 @@ func TestFsCdrDDazRSRExtraFields(t *testing.T) {
|
||||
} else if !reflect.DeepEqual(expCdrExtra[0], fsCdrCfg.CdrsCfg().ExtraFields[0]) { // Kinda deepEqual bug since without index does not match
|
||||
t.Errorf("Expecting: %+v, received: %+v", expCdrExtra, fsCdrCfg.CdrsCfg().ExtraFields)
|
||||
}
|
||||
fsCdr, err := NewFSCdr(simpleJsonCdr, fsCdrCfg)
|
||||
newReader := bytes.NewReader(simpleJsonCdr)
|
||||
fsCdr, err := NewFSCdr(newReader, fsCdrCfg)
|
||||
if err != nil {
|
||||
t.Error("Could not parse cdr", err.Error())
|
||||
}
|
||||
@@ -520,7 +540,8 @@ func TestFsCdrDDazRSRExtraFields(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFsCdrFirstDefined(t *testing.T) {
|
||||
fsCdr, _ := NewFSCdr(body, fsCdrCfg)
|
||||
newReader := bytes.NewReader(body)
|
||||
fsCdr, _ := NewFSCdr(newReader, fsCdrCfg)
|
||||
value := fsCdr.firstDefined([]string{utils.CGR_SUBJECT, utils.CGR_ACCOUNT, FS_USERNAME}, FsUsername)
|
||||
if value != "1001" {
|
||||
t.Errorf("Expecting: 1001, received: %s", value)
|
||||
@@ -530,3 +551,239 @@ func TestFsCdrFirstDefined(t *testing.T) {
|
||||
t.Errorf("Expecting: 1001, received: %s", value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFscdrAsCDR(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
cgrCfg.CdrsCfg().ExtraFields, err = utils.ParseRSRFieldsFromSlice([]string{"PayPalAccount"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fsCdrByte := []byte(` {
|
||||
"variables": {
|
||||
"cgr_orderid": "123",
|
||||
"cgr_partial": "true",
|
||||
"cgr_prerated": "false"
|
||||
}
|
||||
}`)
|
||||
expectedCdr := &CDR{
|
||||
OrderID: 123,
|
||||
ToR: utils.META_VOICE,
|
||||
Source: FS_CDR_SOURCE, Category: cgrCfg.GeneralCfg().DefaultCategory,
|
||||
Tenant: cgrCfg.GeneralCfg().DefaultTenant,
|
||||
RequestType: cgrCfg.GeneralCfg().DefaultReqType,
|
||||
Partial: true,
|
||||
PreRated: false,
|
||||
ExtraFields: map[string]string{
|
||||
"PayPalAccount": "",
|
||||
},
|
||||
Cost: -1,
|
||||
}
|
||||
newReader := bytes.NewReader(fsCdrByte)
|
||||
if fsCdr, err := NewFSCdr(newReader, cgrCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
expectedCdr.CGRID = fsCdr.getCGRID()
|
||||
if cdr, err := fsCdr.AsCDR(""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expectedCdr, cdr) {
|
||||
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expectedCdr), utils.ToJSON(cdr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFscdrAsCdrOrderId(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fsCdrByte := []byte(` {
|
||||
"variables": {
|
||||
"cgr_orderid": "123s"
|
||||
}
|
||||
}`)
|
||||
expectedErr := "strconv.ParseInt: parsing \"123s\": invalid syntax"
|
||||
newReader := bytes.NewReader(fsCdrByte)
|
||||
if fsCdr, err := NewFSCdr(newReader, cgrCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else if _, err := fsCdr.AsCDR(""); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v \n, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFscdrAsCdrSetupTime(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fsCdrByte := []byte(` {
|
||||
"variables": {
|
||||
"start_epoch": "123ss"
|
||||
}
|
||||
}`)
|
||||
expectedErr := "Unsupported time format"
|
||||
newReader := bytes.NewReader(fsCdrByte)
|
||||
if fsCdr, err := NewFSCdr(newReader, cgrCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else if _, err := fsCdr.AsCDR(""); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v \n, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFscdrAsCdrAnswerTime(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fsCdrByte := []byte(` {
|
||||
"variables": {
|
||||
"answer_epoch": "123ss"
|
||||
}
|
||||
}`)
|
||||
expectedErr := "Unsupported time format"
|
||||
newReader := bytes.NewReader(fsCdrByte)
|
||||
if fsCdr, err := NewFSCdr(newReader, cgrCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else if _, err := fsCdr.AsCDR(""); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v \n, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFscdrAsCdrUsage(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fsCdrByte := []byte(` {
|
||||
"variables": {
|
||||
"billsec": "1ss"
|
||||
}
|
||||
}`)
|
||||
expectedErr := "time: unknown unit \"ss\" in duration \"1ss\""
|
||||
newReader := bytes.NewReader(fsCdrByte)
|
||||
if fsCdr, err := NewFSCdr(newReader, cgrCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else if _, err := fsCdr.AsCDR(""); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v \n, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFscdrAsCdrPartial(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fsCdrByte := []byte(` {
|
||||
"variables": {
|
||||
"cgr_partial": "InvalidBoolFormat"
|
||||
}
|
||||
}`)
|
||||
expectedErr := "strconv.ParseBool: parsing \"InvalidBoolFormat\": invalid syntax"
|
||||
newReader := bytes.NewReader(fsCdrByte)
|
||||
if fsCdr, err := NewFSCdr(newReader, cgrCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else if _, err := fsCdr.AsCDR(""); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v \n, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFscdrAsCdrPreRated(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fsCdrByte := []byte(` {
|
||||
"variables": {
|
||||
"cgr_prerated": "InvalidBoolFormat"
|
||||
}
|
||||
}`)
|
||||
expectedErr := "strconv.ParseBool: parsing \"InvalidBoolFormat\": invalid syntax"
|
||||
newReader := bytes.NewReader(fsCdrByte)
|
||||
if fsCdr, err := NewFSCdr(newReader, cgrCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else if _, err := fsCdr.AsCDR(""); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v \n, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFscdrAsCdrFirstDefined(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fsCdrByte := []byte(` {
|
||||
"variables": {
|
||||
"cgr_account": "randomAccount"
|
||||
}
|
||||
}`)
|
||||
expectedCdr := &CDR{
|
||||
ToR: utils.META_VOICE,
|
||||
Source: FS_CDR_SOURCE, Category: cgrCfg.GeneralCfg().DefaultCategory,
|
||||
Tenant: cgrCfg.GeneralCfg().DefaultTenant,
|
||||
RequestType: cgrCfg.GeneralCfg().DefaultReqType,
|
||||
Account: "randomAccount",
|
||||
Subject: "randomAccount",
|
||||
ExtraFields: map[string]string{},
|
||||
Cost: -1,
|
||||
}
|
||||
newReader := bytes.NewReader(fsCdrByte)
|
||||
if fsCdr, err := NewFSCdr(newReader, cgrCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
expectedCdr.CGRID = fsCdr.getCGRID()
|
||||
if cdr, err := fsCdr.AsCDR(""); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expectedCdr, cdr) {
|
||||
t.Errorf("Expected %+v \n, redceived %+v", utils.ToJSON(expectedCdr), utils.ToJSON(cdr))
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestNewFSCdrDecodeError(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expectedErr := "EOF"
|
||||
newReader := bytes.NewReader(nil)
|
||||
if _, err := NewFSCdr(newReader, cgrCfg); err == nil || err.Error() != expectedErr {
|
||||
t.Errorf("Expected %+v, received %+v", expectedErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSearchExtraFieldDefaultType(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
newMap := map[string]interface{}{
|
||||
"variables": map[string]string{
|
||||
"cgr_orderid": "123",
|
||||
},
|
||||
}
|
||||
fsCdr := FSCdr{
|
||||
cgrCfg: cgrCfg,
|
||||
body: newMap,
|
||||
}
|
||||
fsCdr.searchExtraField(utils.EmptyString, newMap)
|
||||
}
|
||||
|
||||
func TestSearchExtraFieldInterface(t *testing.T) {
|
||||
cgrCfg, err := config.NewDefaultCGRConfig()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
newMap := map[string]interface{}{ //There is a slice with no maps
|
||||
"variables": []interface{}{
|
||||
2,
|
||||
"randomValue",
|
||||
true,
|
||||
},
|
||||
}
|
||||
fsCdr := FSCdr{
|
||||
cgrCfg: cgrCfg,
|
||||
body: newMap,
|
||||
}
|
||||
fsCdr.searchExtraField(utils.EmptyString, newMap)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user