This commit is contained in:
DanB
2015-02-06 13:25:03 +01:00
30 changed files with 173 additions and 107 deletions

View File

@@ -21,6 +21,7 @@ package v1
import (
"errors"
"fmt"
"regexp"
"time"
"github.com/cgrates/cgrates/engine"
@@ -120,7 +121,7 @@ type AttrRemAcntActionTriggers struct {
Tenant string // Tenant he account belongs to
Account string // Account name
Direction string // Traffic direction
ActionTriggerId string // Id filtering only specific id to remove
ActionTriggerId string // Id filtering only specific id to remove (can be regexp pattern)
}
// Returns a list of ActionTriggers on an account
@@ -135,7 +136,8 @@ func (self *ApierV1) RemAccountActionTriggers(attrs AttrRemAcntActionTriggers, r
return 0, err
}
for idx, actr := range ub.ActionTriggers {
if len(attrs.ActionTriggerId) != 0 && actr.Id != attrs.ActionTriggerId { // Empty actionTriggerId will match always
match, _ := regexp.MatchString(attrs.ActionTriggerId, actr.Id)
if len(attrs.ActionTriggerId) != 0 && !match {
continue
}
if len(ub.ActionTriggers) != 1 { // Remove by index

View File

@@ -435,7 +435,7 @@ func (self *ApierV1) SetActions(attrs AttrSetActions, reply *string) error {
// Retrieves actions attached to specific ActionsId within cache
func (self *ApierV1) GetActions(actsId string, reply *[]*utils.TPAction) error {
if len(actsId) == 0 {
return fmt.Errorf("%s:ActionsId", utils.ERR_MANDATORY_IE_MISSING, actsId)
return fmt.Errorf("%s ActionsId: %s", utils.ERR_MANDATORY_IE_MISSING, actsId)
}
acts := make([]*utils.TPAction, 0)
engActs, err := self.AccountDb.GetActions(actsId, false)
@@ -534,6 +534,7 @@ func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) error
}
type AttrAddActionTrigger struct {
Id string
Tenant string
Account string
ThresholdType string
@@ -559,7 +560,7 @@ func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
}
at := &engine.ActionTrigger{
Id: utils.GenUUID(),
Id: attr.Id,
ThresholdType: attr.ThresholdType,
ThresholdValue: attr.ThresholdValue,
BalanceId: attr.BalanceId,
@@ -596,6 +597,7 @@ func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string
}
type AttrResetTriggeredAction struct {
Id string
Tenant string
Account string
Direction string
@@ -609,35 +611,41 @@ type AttrResetTriggeredAction struct {
}
func (self *ApierV1) ResetTriggeredActions(attr AttrResetTriggeredAction, reply *string) error {
if attr.Direction == "" {
attr.Direction = engine.OUTBOUND
}
extraParameters, err := json.Marshal(struct {
ThresholdType string
ThresholdValue float64
DestinationId string
BalanceWeight float64
BalanceRatingSubject string
BalanceSharedGroup string
}{
attr.ThresholdType,
attr.ThresholdValue,
attr.DestinationId,
attr.BalanceWeight,
attr.BalanceRatingSubject,
attr.BalanceSharedGroup,
})
if err != nil {
*reply = err.Error()
return err
}
a := &engine.Action{
BalanceType: attr.BalanceType,
Direction: attr.Direction,
ExtraParameters: string(extraParameters),
var a *engine.Action
if attr.Id != "" {
// we can identify the trigge by the id
a = &engine.Action{Id: attr.Id}
} else {
if attr.Direction == "" {
attr.Direction = engine.OUTBOUND
}
extraParameters, err := json.Marshal(struct {
ThresholdType string
ThresholdValue float64
DestinationId string
BalanceWeight float64
BalanceRatingSubject string
BalanceSharedGroup string
}{
attr.ThresholdType,
attr.ThresholdValue,
attr.DestinationId,
attr.BalanceWeight,
attr.BalanceRatingSubject,
attr.BalanceSharedGroup,
})
if err != nil {
*reply = err.Error()
return err
}
a = &engine.Action{
BalanceType: attr.BalanceType,
Direction: attr.Direction,
ExtraParameters: string(extraParameters),
}
}
accID := utils.AccountKey(attr.Tenant, attr.Account, attr.Direction)
_, err = engine.AccLock.Guard(accID, func() (float64, error) {
_, err := engine.AccLock.Guard(accID, func() (float64, error) {
acc, err := self.AccountDb.GetAccount(accID)
if err != nil {
return 0, err

View File

@@ -217,7 +217,7 @@ func TestApierTPTiming(t *testing.T) {
// Test getIds
var rplyTmIds []string
expectedTmIds := []string{"ALWAYS", "ASAP"}
if err := rater.Call("ApierV1.GetTPTimingIds", AttrGetTPTimingIds{tmAlways.TPid, utils.Paginator{0, 0, ""}}, &rplyTmIds); err != nil {
if err := rater.Call("ApierV1.GetTPTimingIds", AttrGetTPTimingIds{tmAlways.TPid, utils.Paginator{Page: 0, ItemsPerPage: 0, SearchTerm: ""}}, &rplyTmIds); err != nil {
t.Error("Calling ApierV1.GetTPTimingIds, got error: ", err.Error())
} else if !reflect.DeepEqual(expectedTmIds, rplyTmIds) {
t.Errorf("Calling ApierV1.GetTPTimingIds expected: %v, received: %v", expectedTmIds, rplyTmIds)
@@ -325,7 +325,7 @@ func TestApierTPRate(t *testing.T) {
// Test getIds
var rplyRtIds []string
expectedRtIds := []string{"RT_FS_USERS"}
if err := rater.Call("ApierV1.GetTPRateIds", AttrGetTPRateIds{rt.TPid, utils.Paginator{0, 0, ""}}, &rplyRtIds); err != nil {
if err := rater.Call("ApierV1.GetTPRateIds", AttrGetTPRateIds{rt.TPid, utils.Paginator{Page: 0, ItemsPerPage: 0, SearchTerm: ""}}, &rplyRtIds); err != nil {
t.Error("Calling ApierV1.GetTPRateIds, got error: ", err.Error())
} else if !reflect.DeepEqual(expectedRtIds, rplyRtIds) {
t.Errorf("Calling ApierV1.GetTPDestinationIds expected: %v, received: %v", expectedRtIds, rplyRtIds)
@@ -382,7 +382,7 @@ func TestApierTPDestinationRate(t *testing.T) {
// Test getIds
var rplyDrIds []string
expectedDrIds := []string{"DR_FREESWITCH_USERS"}
if err := rater.Call("ApierV1.GetTPDestinationRateIds", AttrTPDestinationRateIds{dr.TPid, utils.Paginator{0, 0, ""}}, &rplyDrIds); err != nil {
if err := rater.Call("ApierV1.GetTPDestinationRateIds", AttrTPDestinationRateIds{dr.TPid, utils.Paginator{Page: 0, ItemsPerPage: 0, SearchTerm: ""}}, &rplyDrIds); err != nil {
t.Error("Calling ApierV1.GetTPDestinationRateIds, got error: ", err.Error())
} else if !reflect.DeepEqual(expectedDrIds, rplyDrIds) {
t.Errorf("Calling ApierV1.GetTPDestinationRateIds expected: %v, received: %v", expectedDrIds, rplyDrIds)
@@ -436,7 +436,7 @@ func TestApierTPRatingPlan(t *testing.T) {
// Test getIds
var rplyRpIds []string
expectedRpIds := []string{"RETAIL1"}
if err := rater.Call("ApierV1.GetTPRatingPlanIds", AttrGetTPRatingPlanIds{rp.TPid, utils.Paginator{0, 0, ""}}, &rplyRpIds); err != nil {
if err := rater.Call("ApierV1.GetTPRatingPlanIds", AttrGetTPRatingPlanIds{rp.TPid, utils.Paginator{Page: 0, ItemsPerPage: 0, SearchTerm: ""}}, &rplyRpIds); err != nil {
t.Error("Calling ApierV1.GetTPRatingPlanIds, got error: ", err.Error())
} else if !reflect.DeepEqual(expectedRpIds, rplyRpIds) {
t.Errorf("Calling ApierV1.GetTPRatingPlanIds expected: %v, received: %v", expectedRpIds, rplyRpIds)

View File

@@ -77,7 +77,14 @@ func (self *ApierV1) ImportTPZipFile(attrs AttrImportTPZipFile, reply *string) e
*reply = "ERROR: missing TPid!"
return err
}
csvImporter := engine.TPCSVImporter{attrs.TPid, self.StorDb, path, ',', false, ""}
csvImporter := engine.TPCSVImporter{
TPid: attrs.TPid,
StorDb: self.StorDb,
DirPath: path,
Sep: ',',
Verbose: false,
ImportId: "",
}
if errImport := csvImporter.Run(); errImport != nil {
return errImport
}

View File

@@ -58,7 +58,11 @@ func (self *ApierV1) GetTPActionPlan(attrs AttrGetTPActionPlan, reply *utils.TPA
} else if len(ats) == 0 {
return errors.New(utils.ERR_NOT_FOUND)
} else { // Got the data we need, convert it
atRply := &utils.TPActionPlan{attrs.TPid, attrs.Id, ats[attrs.Id]}
atRply := &utils.TPActionPlan{
TPid: attrs.TPid,
Id: attrs.Id,
ActionPlan: ats[attrs.Id],
}
*reply = *atRply
}
return nil

View File

@@ -56,7 +56,11 @@ func (self *ApierV1) GetTPActionTriggers(attrs AttrGetTPActionTriggers, reply *u
} else if len(atsMap) == 0 {
return errors.New(utils.ERR_NOT_FOUND)
} else {
atRply := &utils.TPActionTriggers{attrs.TPid, attrs.ActionTriggersId, atsMap[attrs.ActionTriggersId]}
atRply := &utils.TPActionTriggers{
TPid: attrs.TPid,
ActionTriggersId: attrs.ActionTriggersId,
ActionTriggers: atsMap[attrs.ActionTriggersId],
}
*reply = *atRply
}
return nil

View File

@@ -22,13 +22,14 @@ import (
"encoding/csv"
"encoding/json"
"fmt"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
"io"
"os"
"strconv"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
const (
@@ -239,7 +240,6 @@ func (cdre *CdrExporter) metaHandler(tag, arg string) (string, error) {
default:
return "", fmt.Errorf("Unsupported METATAG: %s", tag)
}
return "", nil
}
// Compose and cache the header

View File

@@ -121,7 +121,7 @@ func main() {
}
fmt.Println("Welcome to CGRateS console!")
fmt.Println("Type `help` for a list of commands\n")
fmt.Print("Type `help` for a list of commands\n\n")
line := liner.NewLiner()
defer line.Close()

View File

@@ -424,7 +424,7 @@ func main() {
cdrStats.AddQueue(engine.NewCdrStatsFromCdrStatsCfg(cfg.CDRStatConfig), nil)
}
server.RpcRegister(cdrStats)
server.RpcRegister(&v1.CDRStatsV1{cdrStats}) // Public APIs
server.RpcRegister(&v1.CDRStatsV1{CdrStats: cdrStats}) // Public APIs
}
responder := &engine.Responder{ExitChan: exitChan}

View File

@@ -116,7 +116,14 @@ func main() {
if *tpid == "" {
log.Fatal("TPid required, please define it via *-tpid* command argument.")
}
csvImporter := engine.TPCSVImporter{*tpid, storDb, *dataPath, ',', *verbose, *runId}
csvImporter := engine.TPCSVImporter{
TPid: *tpid,
StorDb: storDb,
DirPath: *dataPath,
Sep: ',',
Verbose: *verbose,
ImportId: *runId,
}
if errImport := csvImporter.Run(); errImport != nil {
log.Fatal(errImport)
}
@@ -218,7 +225,17 @@ func main() {
if *flush {
dstIds, rplIds, rpfIds, rpAliases, lcrIds = nil, nil, nil, nil, nil // Should reload all these on flush
}
if err = rater.Call("ApierV1.ReloadCache", utils.ApiReloadCache{dstIds, rplIds, rpfIds, actIds, shgIds, rpAliases, accAliases, lcrIds, dcs}, &reply); err != nil {
if err = rater.Call("ApierV1.ReloadCache", utils.ApiReloadCache{
DestinationIds: dstIds,
RatingPlanIds: rplIds,
RatingProfileIds: rpfIds,
ActionIds: actIds,
SharedGroupIds: shgIds,
RpAliases: rpAliases,
AccAliases: accAliases,
LCRIds: lcrIds,
DerivedChargers: dcs,
}, &reply); err != nil {
log.Printf("WARNING: Got error on cache reload: %s\n", err.Error())
}
actTmgIds, _ := loader.GetLoadedIds(engine.ACTION_TIMING_PREFIX)

View File

@@ -109,7 +109,7 @@ func durRemoteRater(cd *engine.CallDescriptor) (time.Duration, error) {
result := engine.CallCost{}
client, err := rpc.Dial("tcp", *raterAddress)
if err != nil {
return nilDuration, fmt.Errorf("Could not connect to engine: ", err.Error())
return nilDuration, fmt.Errorf("Could not connect to engine: %s", err.Error())
}
defer client.Close()
start := time.Now()

View File

@@ -21,6 +21,7 @@ package engine
import (
"encoding/json"
"fmt"
"regexp"
"sort"
"time"
@@ -28,7 +29,7 @@ import (
)
type ActionTrigger struct {
Id string // uniquely identify the trigger
Id string // for visual identification
ThresholdType string //*min_counter, *max_counter, *min_balance, *max_balance
// stats: *min_asr, *max_asr, *min_acd, *max_acd, *min_acc, *max_acc
ThresholdValue float64
@@ -102,6 +103,11 @@ func (at *ActionTrigger) Match(a *Action) bool {
if a == nil {
return true
}
// if we have Id than we can draw an early conclusion
if a.Id != "" {
match, _ := regexp.MatchString(a.Id, at.Id)
return match
}
id := a.BalanceType == "" || at.BalanceType == a.BalanceType
direction := a.Direction == "" || at.BalanceDirection == a.Direction
thresholdType, thresholdValue, destinationId, weight, ratingSubject, category, sharedGroup := true, true, true, true, true, true, true

View File

@@ -91,7 +91,7 @@ func TestBalanceMatchFilter(t *testing.T) {
mb1 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
mb2 := &Balance{Weight: 1, precision: 1, RatingSubject: "", DestinationId: ""}
if !mb1.MatchFilter(mb2) {
t.Error("Match filter failure: %+v == %+v", mb1, mb2)
t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
}
}
@@ -99,7 +99,7 @@ func TestBalanceMatchFilterEmpty(t *testing.T) {
mb1 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
mb2 := &Balance{}
if !mb1.MatchFilter(mb2) {
t.Error("Match filter failure: %+v == %+v", mb1, mb2)
t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
}
}
@@ -107,7 +107,7 @@ func TestBalanceMatchFilterId(t *testing.T) {
mb1 := &Balance{Id: "T1", Weight: 2, precision: 2, RatingSubject: "2", DestinationId: "NAT"}
mb2 := &Balance{Id: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
if !mb1.MatchFilter(mb2) {
t.Error("Match filter failure: %+v == %+v", mb1, mb2)
t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
}
}
@@ -115,7 +115,7 @@ func TestBalanceMatchFilterDiffId(t *testing.T) {
mb1 := &Balance{Id: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
mb2 := &Balance{Id: "T2", Weight: 1, precision: 1, RatingSubject: "1", DestinationId: ""}
if mb1.MatchFilter(mb2) {
t.Error("Match filter failure: %+v != %+v", mb1, mb2)
t.Errorf("Match filter failure: %+v != %+v", mb1, mb2)
}
}
@@ -235,6 +235,6 @@ func TestBalanceMatchActionTriggerSharedGroup(t *testing.T) {
func TestBalanceIsDefault(t *testing.T) {
b := &Balance{Weight: 0}
if !b.IsDefault() {
t.Errorf("Balance should be default: +v", b)
t.Errorf("Balance should be default: %+v", b)
}
}

View File

@@ -457,6 +457,7 @@ If the user has postpayed plan it returns -1.
*/
func (origCD *CallDescriptor) getMaxSessionDuration(origAcc *Account) (time.Duration, error) {
// clone the account for discarding chenges on debit dry run
//log.Printf("ORIG CD: %+v", origCD)
account := origAcc.Clone()
if account.AllowNegative {
return -1, nil
@@ -538,6 +539,7 @@ func (cd *CallDescriptor) debit(account *Account, dryRun bool) (cc *CallCost, er
if cd.TOR == "" {
cd.TOR = MINUTES
}
//log.Printf("Debit CD: %+v", cd)
cc, err = account.debitCreditBalance(cd, !dryRun, dryRun)
//log.Print("HERE: ", cc, err)
if err != nil {

View File

@@ -679,7 +679,7 @@ func (csvr *CSVReader) LoadActions() (err error) {
return fmt.Errorf("Could not parse action weight: %v", err)
}
a := &Action{
Id: utils.GenUUID(),
Id: tag,
ActionType: record[ACTSCSVIDX_ACTION],
BalanceType: record[ACTSCSVIDX_BALANCE_TYPE],
Direction: record[ACTSCSVIDX_DIRECTION],
@@ -719,6 +719,12 @@ func (csvr *CSVReader) LoadActions() (err error) {
if _, err := utils.ParseDate(a.ExpirationString); err != nil {
return fmt.Errorf("Could not parse expiration time: %v", err)
}
// update Id
idx := 0
if previous, ok := csvr.actions[tag]; ok {
idx = len(previous)
}
a.Id = a.Id + strconv.Itoa(idx)
csvr.actions[tag] = append(csvr.actions[tag], a)
}
return
@@ -815,7 +821,7 @@ func (csvr *CSVReader) LoadActionTriggers() (err error) {
}
at := &ActionTrigger{
Id: utils.GenUUID(),
Id: tag,
ThresholdType: record[ATRIGCSVIDX_THRESHOLD_TYPE],
ThresholdValue: value,
Recurrent: recurrent,
@@ -834,6 +840,12 @@ func (csvr *CSVReader) LoadActionTriggers() (err error) {
ActionsId: record[ATRIGCSVIDX_ACTIONS_TAG],
Weight: weight,
}
// update Id
idx := 0
if previous, ok := csvr.actionsTriggers[tag]; ok {
idx = len(previous)
}
at.Id = at.Id + strconv.Itoa(idx)
csvr.actionsTriggers[tag] = append(csvr.actionsTriggers[tag], at)
}
return

View File

@@ -696,7 +696,7 @@ func TestLoadActions(t *testing.T) {
as1 := csvr.actions["MINI"]
expected := []*Action{
&Action{
Id: as1[0].Id,
Id: "MINI0",
ActionType: TOPUP_RESET,
BalanceType: CREDIT,
Direction: OUTBOUND,
@@ -710,7 +710,7 @@ func TestLoadActions(t *testing.T) {
},
},
&Action{
Id: as1[1].Id,
Id: "MINI1",
ActionType: TOPUP,
BalanceType: MINUTES,
Direction: OUTBOUND,
@@ -732,7 +732,7 @@ func TestLoadActions(t *testing.T) {
as2 := csvr.actions["SHARED"]
expected = []*Action{
&Action{
Id: as2[0].Id,
Id: "SHARED0",
ActionType: TOPUP,
BalanceType: CREDIT,
Direction: OUTBOUND,
@@ -867,7 +867,7 @@ func TestLoadActionTriggers(t *testing.T) {
}
atr := csvr.actionsTriggers["STANDARD_TRIGGER"][0]
expected := &ActionTrigger{
Id: atr.Id,
Id: "STANDARD_TRIGGER0",
BalanceType: MINUTES,
BalanceDirection: OUTBOUND,
ThresholdType: TRIGGER_MIN_COUNTER,
@@ -882,7 +882,7 @@ func TestLoadActionTriggers(t *testing.T) {
}
atr = csvr.actionsTriggers["STANDARD_TRIGGER"][1]
expected = &ActionTrigger{
Id: atr.Id,
Id: "STANDARD_TRIGGER1",
BalanceType: MINUTES,
BalanceDirection: OUTBOUND,
ThresholdType: TRIGGER_MAX_BALANCE,

View File

@@ -22,6 +22,7 @@ import (
"errors"
"fmt"
"log"
"strconv"
"strings"
"github.com/cgrates/cgrates/utils"
@@ -561,7 +562,7 @@ func (dbr *DbReader) LoadActions() (err error) {
acts := make([]*Action, len(tpacts))
for idx, tpact := range tpacts {
acts[idx] = &Action{
Id: utils.GenUUID(),
Id: tag + strconv.Itoa(idx),
ActionType: tpact.Identifier,
BalanceType: tpact.BalanceType,
Direction: tpact.Direction,
@@ -650,7 +651,7 @@ func (dbr *DbReader) LoadActionTriggers() (err error) {
for idx, apiAtr := range atrsLst {
balance_expiration_date, _ := utils.ParseTimeDetectLayout(apiAtr.BalanceExpirationDate)
atrs[idx] = &ActionTrigger{
Id: utils.GenUUID(),
Id: key + strconv.Itoa(idx),
ThresholdType: apiAtr.ThresholdType,
ThresholdValue: apiAtr.ThresholdValue,
Recurrent: apiAtr.Recurrent,
@@ -841,7 +842,7 @@ func (dbr *DbReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions)
enacts := make([]*Action, len(tpacts))
for idx, tpact := range tpacts {
enacts[idx] = &Action{
Id: utils.GenUUID(),
Id: tag + strconv.Itoa(idx),
ActionType: tpact.Identifier,
BalanceType: tpact.BalanceType,
Direction: tpact.Direction,

View File

@@ -76,7 +76,7 @@ func TestStatsSimplifyCDR(t *testing.T) {
cdr.AnswerTime != qcdr.AnswerTime ||
cdr.Usage != qcdr.Usage ||
cdr.Cost != qcdr.Cost {
t.Error("Failed to simplify cdr: %+v", qcdr)
t.Errorf("Failed to simplify cdr: %+v", qcdr)
}
}
@@ -101,83 +101,83 @@ func TestAcceptCdr(t *testing.T) {
}
sq.conf = &CdrStats{}
if sq.conf.AcceptCdr(cdr) != true {
t.Error("Should have accepted thif CDR: %+v", cdr)
t.Errorf("Should have accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{TOR: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{CdrHost: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{CdrSource: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{Direction: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{Tenant: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{Category: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{Account: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{Subject: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{RatedAccount: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{RatedSubject: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{DestinationPrefix: []string{"test"}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{DestinationPrefix: []string{"test", "123"}}
if sq.conf.AcceptCdr(cdr) != true {
t.Error("Should have accepted thif CDR: %+v", cdr)
t.Errorf("Should have accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{SetupInterval: []time.Time{time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC)}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{SetupInterval: []time.Time{time.Date(2014, 7, 3, 13, 42, 0, 0, time.UTC), time.Date(2014, 7, 3, 13, 43, 0, 0, time.UTC)}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{SetupInterval: []time.Time{time.Date(2014, 7, 3, 13, 42, 0, 0, time.UTC)}}
if sq.conf.AcceptCdr(cdr) != true {
t.Error("Should have accepted thif CDR: %+v", cdr)
t.Errorf("Should have accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{SetupInterval: []time.Time{time.Date(2014, 7, 3, 13, 42, 0, 0, time.UTC), time.Date(2014, 7, 3, 13, 43, 0, 1, time.UTC)}}
if sq.conf.AcceptCdr(cdr) != true {
t.Error("Should have accepted thif CDR: %+v", cdr)
t.Errorf("Should have accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{UsageInterval: []time.Duration{11 * time.Second}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{UsageInterval: []time.Duration{1 * time.Second, 10 * time.Second}}
if sq.conf.AcceptCdr(cdr) == true {
t.Error("Should have NOT accepted thif CDR: %+v", cdr)
t.Errorf("Should have NOT accepted thif CDR: %+v", cdr)
}
sq.conf = &CdrStats{UsageInterval: []time.Duration{10 * time.Second, 11 * time.Second}}
if sq.conf.AcceptCdr(cdr) != true {
t.Error("Should have accepted thif CDR: %+v", cdr)
t.Errorf("Should have accepted thif CDR: %+v", cdr)
}
}
@@ -185,12 +185,12 @@ func TestStatsQueueIds(t *testing.T) {
cdrStats := NewStats(dataStorage)
ids := []string{}
if err := cdrStats.GetQueueIds(0, &ids); err != nil {
t.Error("Error getting queue ids: ", err)
t.Error("Errorf getting queue ids: ", err)
}
result := len(ids)
expected := 2
if result != expected {
t.Errorf("Error loading stats queues. Expected %v was %v", expected, result)
t.Errorf("Errorf loading stats queues. Expected %v was %v", expected, result)
}
}

View File

@@ -77,7 +77,7 @@ func TestMySQLSetGetTPTiming(t *testing.T) {
if tmgs, err := mysqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil {
t.Error(err.Error())
} else if !reflect.DeepEqual(tm, tmgs[tm.TimingId]) {
t.Errorf("Expecting: %+v, received: %+v", tmgs[tm.TimingId])
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[tm.TimingId])
}
}

View File

@@ -67,7 +67,7 @@ func TestPSQLSetGetTPTiming(t *testing.T) {
if tmgs, err := psqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil {
t.Error(err.Error())
} else if !reflect.DeepEqual(tm, tmgs[tm.TimingId]) {
t.Errorf("Expecting: %+v, received: %+v", tmgs[tm.TimingId])
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[tm.TimingId])
}
// Update
tm.Time = "00:00:01"
@@ -77,7 +77,7 @@ func TestPSQLSetGetTPTiming(t *testing.T) {
if tmgs, err := psqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil {
t.Error(err.Error())
} else if !reflect.DeepEqual(tm, tmgs[tm.TimingId]) {
t.Errorf("Expecting: %+v, received: %+v", tmgs[tm.TimingId])
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[tm.TimingId])
}
}

View File

@@ -87,7 +87,7 @@ func (rs *RedisStorage) CacheRating(dKeys, rpKeys, rpfKeys, alsKeys, lcrKeys []s
}
for _, key := range dKeys {
if len(key) <= len(DESTINATION_PREFIX) {
Logger.Warning(fmt.Sprintf("Got malformed destination id: ", key))
Logger.Warning(fmt.Sprintf("Got malformed destination id: %s", key))
continue
}
if _, err = rs.GetDestination(key[len(DESTINATION_PREFIX):]); err != nil {

View File

@@ -478,7 +478,7 @@ func (self *SQLStorage) SetTPLCRs(tpid string, lcrs map[string]*LCR) error {
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
buffer.WriteRune(',')
}
buffer.WriteString(fmt.Sprintf("('%s','%s','%s','%s','%s','%s','%s','%v','%v')",
buffer.WriteString(fmt.Sprintf("('%s','%s','%s','%s','%s','%s','%s','%v','%v', '%v')",
tpid, lcr.Direction, lcr.Tenant, lcr.Customer, entry.DestinationId, entry.Category, entry.Strategy, entry.Suppliers, act.ActivationTime, entry.Weight))
i++
}
@@ -608,10 +608,10 @@ func (self *SQLStorage) SetTPActionTriggers(tpid string, ats map[string][]*utils
tx.Rollback()
return err
}
for _, at := range aTriggers {
for idx, at := range aTriggers {
saved := tx.Save(TpActionTrigger{
Tpid: tpid,
Tag: atId,
Tag: atId + strconv.Itoa(idx),
ThresholdType: at.ThresholdType,
ThresholdValue: at.ThresholdValue,
Recurrent: at.Recurrent,

View File

@@ -133,7 +133,7 @@ func TestExecuteActions(t *testing.T) {
} else if len(acnt.BalanceMap) != 2 {
t.Error("Account does not have enough balances: ", acnt.BalanceMap)
} else if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 40 {
t.Errorf("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
t.Error("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
} else if acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value != 10 {
t.Error("Account does not have enough monetary balance", acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value)
}

View File

@@ -131,7 +131,7 @@ func TestExecuteActions2(t *testing.T) {
} else if len(acnt.BalanceMap) != 2 {
t.Error("Account does not have enough balances: ", acnt.BalanceMap)
} else if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 40 {
t.Errorf("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
t.Error("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
} else if acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value != 0 {
t.Error("Account does not have enough monetary balance", acnt.BalanceMap[engine.CREDIT+engine.OUTBOUND][0].Value)
}

View File

@@ -129,7 +129,7 @@ func TestExecuteActions3(t *testing.T) {
} else if len(acnt.BalanceMap) != 1 {
t.Error("Account does not have enough balances: ", acnt.BalanceMap)
} else if acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value != 40 {
t.Errorf("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
t.Error("Account does not have enough minutes in balance", acnt.BalanceMap[engine.MINUTES+engine.OUTBOUND][0].Value)
}
}

View File

@@ -19,12 +19,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package sessionmanager
import (
"fmt"
"encoding/json"
"strings"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
"github.com/cgrates/osipsdagram"
"strings"
"time"
)
/*
@@ -62,7 +63,8 @@ func (osipsev *OsipsEvent) AsEvent(evStr string) utils.Event {
}
func (osipsev *OsipsEvent) String() string {
return fmt.Sprintf("%+v", osipsev)
mrsh, _ := json.Marshal(osipsev)
return string(mrsh)
}
func (osipsev *OsipsEvent) GetName() string {

View File

@@ -22,12 +22,13 @@ import (
"bytes"
"errors"
"fmt"
"strings"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
"github.com/cgrates/osipsdagram"
"strings"
"time"
)
func NewOSipsSessionManager(cfg *config.CGRConfig, rater, cdrsrv engine.Connector) (*OsipsSessionManager, error) {
@@ -133,7 +134,6 @@ func (osm *OsipsSessionManager) SubscribeEvents(evStop chan struct{}) error {
time.Sleep(osm.cgrCfg.OsipsEvSubscInterval)
}
}
return nil
}
func (osm *OsipsSessionManager) OnOpensipsStart(cdrDagram *osipsdagram.OsipsEvent) {

View File

@@ -514,7 +514,7 @@ type TPActionTiming struct {
type TPActionTriggers struct {
TPid string // Tariff plan id
ActionTriggersId string // Profile id
ActionTriggersId string // action trigger id
ActionTriggers []*TPActionTrigger // Set of triggers grouped in this profile
}
@@ -531,6 +531,7 @@ func (self *TPActionTriggers) AsExportSlice() [][]string {
}
type TPActionTrigger struct {
Id string
ThresholdType string // This threshold type
ThresholdValue float64 // Threshold
Recurrent bool // reset executed flag each run

View File

@@ -35,7 +35,7 @@ func TestNewRSRField1(t *testing.T) {
}
// Separator escaped
if rsrField, err := NewRSRField(`~sip_redirected_to:s\/sip:\+49(\d+)@/0$1/`); err == nil {
t.Error("Parse error, field rule does not contain correct number of separators, received: %v", rsrField)
t.Errorf("Parse error, field rule does not contain correct number of separators, received: %v", rsrField)
}
// One extra separator but escaped
expRSRField3 := &RSRField{Id: "sip_redirected_to",

View File

@@ -193,11 +193,11 @@ func TestUsageMultiply(t *testing.T) {
func TestCostMultiply(t *testing.T) {
cdr := StoredCdr{Cost: 1.01}
if cdr.CostMultiply(1.19, 4); cdr.Cost != 1.2019 {
t.Error("Unexpected cost after multiply: %v", cdr.Cost)
t.Errorf("Unexpected cost after multiply: %v", cdr.Cost)
}
cdr = StoredCdr{Cost: 1.01}
if cdr.CostMultiply(1000, 0); cdr.Cost != 1010 {
t.Error("Unexpected cost after multiply: %v", cdr.Cost)
t.Errorf("Unexpected cost after multiply: %v", cdr.Cost)
}
}