mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Merge branch 'master' into console-ng
This commit is contained in:
@@ -1315,6 +1315,30 @@ func TestGetCallCostLog(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaxDebitInexistentAcnt(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
cc := &engine.CallCost{}
|
||||
cd := engine.CallDescriptor{
|
||||
Direction: "*out",
|
||||
Tenant: "cgrates.org",
|
||||
TOR: "call",
|
||||
Subject: "INVALID",
|
||||
Account: "INVALID",
|
||||
Destination: "1002",
|
||||
TimeStart: time.Date(2014, 3, 27, 10, 42, 26, 0, time.UTC),
|
||||
TimeEnd: time.Date(2014, 3, 27, 10, 42, 26, 0, time.UTC).Add(time.Duration(10) * time.Second),
|
||||
}
|
||||
if err := rater.Call("Responder.MaxDebit", cd, cc); err == nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if err := rater.Call("Responder.Debit", cd, cc); err == nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCdrServer(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
|
||||
@@ -118,7 +118,8 @@ func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.E
|
||||
}
|
||||
}
|
||||
csvWriter.Close()
|
||||
*reply = utils.ExportedFileCdrs{ExportedFilePath: filePath, TotalRecords: len(cdrs), ExportedCgrIds: exportedIds, UnexportedCgrIds: unexportedIds,
|
||||
*reply = utils.ExportedFileCdrs{ExportedFilePath: filePath, TotalRecords: len(cdrs), TotalCost: csvWriter.TotalCost(),
|
||||
ExportedCgrIds: exportedIds, UnexportedCgrIds: unexportedIds,
|
||||
FirstOrderId: csvWriter.FirstOrderId(), LastOrderId: csvWriter.LastOrderId()}
|
||||
case utils.CDRE_FIXED_WIDTH:
|
||||
if len(exportDir) == 0 {
|
||||
@@ -155,7 +156,8 @@ func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.E
|
||||
}
|
||||
}
|
||||
fww.Close()
|
||||
*reply = utils.ExportedFileCdrs{ExportedFilePath: filePath, TotalRecords: len(cdrs), ExportedCgrIds: exportedIds, UnexportedCgrIds: unexportedIds,
|
||||
*reply = utils.ExportedFileCdrs{ExportedFilePath: filePath, TotalRecords: len(cdrs), TotalCost: fww.TotalCost(),
|
||||
ExportedCgrIds: exportedIds, UnexportedCgrIds: unexportedIds,
|
||||
FirstOrderId: fww.FirstOrderId(), LastOrderId: fww.LastOrderId()}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
type CdrWriter interface {
|
||||
FirstOrderId() int64
|
||||
LastOrderId() int64
|
||||
TotalCost() float64
|
||||
WriteCdr(cdr *utils.StoredCdr) string
|
||||
Close()
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ type CsvCdrWriter struct {
|
||||
maskLen int
|
||||
exportedFields []*utils.RSRField // The fields exported, order important
|
||||
firstExpOrderId, lastExpOrderId int64
|
||||
totalCost float64 // Cummulated cost of all the
|
||||
}
|
||||
|
||||
func NewCsvCdrWriter(writer io.Writer, costShiftDigits, roundDecimals int, maskDestId string, maskLen int, exportedFields []*utils.RSRField) *CsvCdrWriter {
|
||||
@@ -47,6 +48,10 @@ func (csvwr *CsvCdrWriter) LastOrderId() int64 {
|
||||
return csvwr.lastExpOrderId
|
||||
}
|
||||
|
||||
func (csvwr *CsvCdrWriter) TotalCost() float64 {
|
||||
return csvwr.totalCost
|
||||
}
|
||||
|
||||
func (csvwr *CsvCdrWriter) WriteCdr(cdr *utils.StoredCdr) error {
|
||||
row := make([]string, len(csvwr.exportedFields))
|
||||
for idx, fld := range csvwr.exportedFields {
|
||||
@@ -69,6 +74,8 @@ func (csvwr *CsvCdrWriter) WriteCdr(cdr *utils.StoredCdr) error {
|
||||
if csvwr.lastExpOrderId < cdr.OrderId {
|
||||
csvwr.lastExpOrderId = cdr.OrderId
|
||||
}
|
||||
csvwr.totalCost += cdr.Cost
|
||||
csvwr.totalCost = utils.Round(csvwr.totalCost, csvwr.roundDecimals, utils.ROUNDING_MIDDLE)
|
||||
return csvwr.writer.Write(row)
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ func TestCsvCdrWriter(t *testing.T) {
|
||||
cfg, _ := config.NewDefaultCGRConfig()
|
||||
exportedFields := append(cfg.CdreExportedFields, &utils.RSRField{Id: "extra3"}, &utils.RSRField{Id: "dummy_extra"}, &utils.RSRField{Id: "extra1"})
|
||||
csvCdrWriter := NewCsvCdrWriter(writer, 0, 4, "", -1, exportedFields)
|
||||
ratedCdr := &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), AccId: "dsafdsaf", CdrHost: "192.168.1.1", ReqType: "rated", Direction: "*out", Tenant: "cgrates.org",
|
||||
ratedCdr := &utils.StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Unix(1383813745, 0).UTC().String()), AccId: "dsafdsaf", CdrHost: "192.168.1.1",
|
||||
ReqType: "rated", Direction: "*out", Tenant: "cgrates.org",
|
||||
TOR: "call", Account: "1001", Subject: "1001", Destination: "1002", SetupTime: time.Unix(1383813745, 0).UTC(), AnswerTime: time.Unix(1383813746, 0).UTC(),
|
||||
Duration: time.Duration(10) * time.Second, MediationRunId: utils.DEFAULT_RUNID,
|
||||
ExtraFields: map[string]string{"extra1": "val_extra1", "extra2": "val_extra2", "extra3": "val_extra3"}, Cost: 1.01,
|
||||
@@ -44,4 +45,7 @@ func TestCsvCdrWriter(t *testing.T) {
|
||||
if result != expected {
|
||||
t.Errorf("Expected: \n%s received: \n%s.", expected, result)
|
||||
}
|
||||
if csvCdrWriter.TotalCost() != 1.01 {
|
||||
t.Error("Unexpected TotalCost: ", csvCdrWriter.TotalCost())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +172,10 @@ func (fwv *FixedWidthCdrWriter) LastOrderId() int64 {
|
||||
return fwv.lastExpOrderId
|
||||
}
|
||||
|
||||
func (fwv *FixedWidthCdrWriter) TotalCost() float64 {
|
||||
return fwv.totalCost
|
||||
}
|
||||
|
||||
// Writes the header into it's buffer
|
||||
func (fwv *FixedWidthCdrWriter) ComposeHeader() error {
|
||||
header := ""
|
||||
|
||||
@@ -130,6 +130,9 @@ func TestWriteCdr(t *testing.T) {
|
||||
if fwWriter.LastOrderId() != 1 {
|
||||
t.Error("Unexpected LastOrderId", fwWriter.LastOrderId())
|
||||
}
|
||||
if fwWriter.TotalCost() != utils.Round(cdr.Cost, fwWriter.roundDecimals, utils.ROUNDING_MIDDLE) {
|
||||
t.Error("Unexpected TotalCost: ", fwWriter.TotalCost())
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteCdrs(t *testing.T) {
|
||||
@@ -199,4 +202,7 @@ func TestWriteCdrs(t *testing.T) {
|
||||
if fwWriter.LastOrderId() != 4 {
|
||||
t.Error("Unexpected LastOrderId", fwWriter.LastOrderId())
|
||||
}
|
||||
if fwWriter.TotalCost() != 5.9957 {
|
||||
t.Error("Unexpected TotalCost: ", fwWriter.TotalCost())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"log"
|
||||
"net/rpc"
|
||||
"os"
|
||||
"runtime"
|
||||
//"runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -287,7 +287,7 @@ func main() {
|
||||
if *pidFile != "" {
|
||||
writePid()
|
||||
}
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
// runtime.GOMAXPROCS(runtime.NumCPU()) // For now it slows down computing due to CPU management, to be reviewed in future Go releases
|
||||
|
||||
cfg, err = config.NewCGRConfigFromFile(cfgPath)
|
||||
if err != nil {
|
||||
|
||||
@@ -60,7 +60,7 @@ func TestParseXmlConfig(t *testing.T) {
|
||||
<field name="CallId" type="cdrfield" value="accid" width="16"/>
|
||||
<field name="Filler" type="filler" width="8"/>
|
||||
<field name="Filler" type="filler" width="8"/>
|
||||
<field name="TerminationCode" type="concatenated_cdrfield" value="operator,product" width="5"/>
|
||||
<field name="TerminationCode" type="cdrfield" value='~cost_details:s/"MatchedDestId":".+_(\s\s\s\s\s)"/$1/' width="5"/>
|
||||
<field name="Cost" type="cdrfield" value="cost" padding="zeroleft" width="9"/>
|
||||
<field name="CalledMask" type="cdrfield" value="calledmask" width="1"/>
|
||||
</fields>
|
||||
|
||||
@@ -46,7 +46,11 @@ func (rs *Responder) GetCost(arg CallDescriptor, reply *CallCost) (err error) {
|
||||
r, e := AccLock.GuardGetCost(arg.GetAccountKey(), func() (*CallCost, error) {
|
||||
return arg.GetCost()
|
||||
})
|
||||
*reply, err = *r, e
|
||||
if e != nil {
|
||||
return e
|
||||
} else if r != nil {
|
||||
*reply = *r
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -59,7 +63,11 @@ func (rs *Responder) Debit(arg CallDescriptor, reply *CallCost) (err error) {
|
||||
r, e := AccLock.GuardGetCost(arg.GetAccountKey(), func() (*CallCost, error) {
|
||||
return arg.Debit()
|
||||
})
|
||||
*reply, err = *r, e
|
||||
if e != nil {
|
||||
return e
|
||||
} else if r != nil {
|
||||
*reply = *r
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -72,7 +80,11 @@ func (rs *Responder) MaxDebit(arg CallDescriptor, reply *CallCost) (err error) {
|
||||
r, e := AccLock.GuardGetCost(arg.GetAccountKey(), func() (*CallCost, error) {
|
||||
return arg.MaxDebit()
|
||||
})
|
||||
*reply, err = *r, e
|
||||
if e != nil {
|
||||
return e
|
||||
} else if r != nil {
|
||||
*reply = *r
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -347,6 +347,7 @@ type AttrExpFileCdrs struct {
|
||||
type ExportedFileCdrs struct {
|
||||
ExportedFilePath string // Full path to the newly generated export file
|
||||
TotalRecords int // Number of CDRs to be exported
|
||||
TotalCost float64 // Sum of all costs in exported CDRs
|
||||
FirstOrderId, LastOrderId int64 // The order id of the last exported CDR
|
||||
ExportedCgrIds []string // List of successfuly exported cgrids in the file
|
||||
UnexportedCgrIds map[string]string // Map of errored CDRs, map key is cgrid, value will be the error string
|
||||
|
||||
@@ -131,7 +131,7 @@ func ParseTimeDetectLayout(tmStr string) (time.Time, error) {
|
||||
} else {
|
||||
return time.Unix(tmstmp, 0), nil
|
||||
}
|
||||
case len(tmStr) == 0: // Time probably missing from request
|
||||
case tmStr == "0" || len(tmStr) == 0: // Time probably missing from request
|
||||
return nilTime, nil
|
||||
}
|
||||
return nilTime, errors.New("Unsupported time format")
|
||||
|
||||
@@ -40,3 +40,12 @@ func TestProcessReSearchReplace2(t *testing.T) {
|
||||
t.Error("Unexpected output from SearchReplace: ", outStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessReSearchReplace3(t *testing.T) { //"MatchedDestId":"CST_31800_DE080"
|
||||
rsr := &ReSearchReplace{regexp.MustCompile(`"MatchedDestId":".+_(\w{5})"`), "$1"}
|
||||
source := `[{"TimeStart":"2014-04-15T22:17:57+02:00","TimeEnd":"2014-04-15T22:18:01+02:00","Cost":0,"RateInterval":{"Timing":{"Years":[],"Months":[],"MonthDays":[],"WeekDays":[],"StartTime":"00:00:00","EndTime":""},"Rating":{"ConnectFee":0,"Rates":[{"GroupIntervalStart":0,"Value":0,"RateIncrement":1000000000,"RateUnit":60000000000}],"RoundingMethod":"*middle","RoundingDecimals":4},"Weight":10},"CallDuration":4000000000,"Increments":null,"MatchedSubject":"*out:sip.test.cgrates.org:call:*any","MatchedPrefix":"+49800","MatchedDestId":"CST_31800_DE080"}]`
|
||||
expectOut := "DE080"
|
||||
if outStr := rsr.Process(source); outStr != expectOut {
|
||||
t.Error("Unexpected output from SearchReplace: ", outStr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,3 +92,12 @@ func TestNewRSRFieldDDz(t *testing.T) {
|
||||
t.Errorf("Unexpected RSRField received: %v", rsrField)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRSRFieldIvo(t *testing.T) {
|
||||
expectRSRField := &RSRField{Id: "cost_details", RSRule: &ReSearchReplace{regexp.MustCompile(`MatchedDestId":".+_(\s\s\s\s\s)"`), "$1"}}
|
||||
if rsrField, err := NewRSRField(`~cost_details:s/MatchedDestId":".+_(\s\s\s\s\s)"/$1/`); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(rsrField, expectRSRField) {
|
||||
t.Errorf("Unexpected RSRField received: %v", rsrField)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,6 +194,14 @@ func TestParseTimeDetectLayout(t *testing.T) {
|
||||
} else if !fsTm.Equal(expectedTime) {
|
||||
t.Errorf("Unexpected time parsed: %v, expecting: %v", fsTm, expectedTime)
|
||||
}
|
||||
fsTmstampStr = "0"
|
||||
fsTm, err = ParseTimeDetectLayout(fsTmstampStr)
|
||||
expectedTime = time.Time{}
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else if !fsTm.Equal(expectedTime) {
|
||||
t.Errorf("Unexpected time parsed: %v, expecting: %v", fsTm, expectedTime)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseDateUnix(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user