func TestSmOsipsJsonCfg(t *testing.T) { eCfg := &SmOsipsJsonCfg{ Enabled: utils.BoolPointer(false), Listen_udp: utils.StringPointer("127.0.0.1:2020"), Ha_rater: &[]*HaPoolJsonCfg{ &HaPoolJsonCfg{ Server: utils.StringPointer("internal"), Timeout: utils.StringPointer("100ms"), }}, Ha_cdrs: &[]*HaPoolJsonCfg{ &HaPoolJsonCfg{ Server: utils.StringPointer("internal"), Timeout: utils.StringPointer("100ms"), }}, Create_cdr: utils.BoolPointer(false), Debit_interval: utils.StringPointer("10s"), Min_call_duration: utils.StringPointer("0s"), Max_call_duration: utils.StringPointer("3h"), Events_subscribe_interval: utils.StringPointer("60s"), Mi_addr: utils.StringPointer("127.0.0.1:8020"), } if cfg, err := dfCgrJsonCfg.SmOsipsJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", cfg) } }
func TestApierV2itSetAccountActionTriggers(t *testing.T) { attrs := AttrSetAccountActionTriggers{ Tenant: "cgrates.org", Account: "dan", GroupID: utils.StringPointer("MONITOR_MAX_BALANCE"), ThresholdType: utils.StringPointer(utils.TRIGGER_MAX_BALANCE), ThresholdValue: utils.Float64Pointer(50), BalanceType: utils.StringPointer(utils.MONETARY), ActionsID: utils.StringPointer("DISABLE_ACCOUNT"), } var reply string if err := apierRPC.Call("ApierV2.SetAccountActionTriggers", attrs, &reply); err != nil { t.Error(err) } var ats engine.ActionTriggers if err := apierRPC.Call("ApierV2.GetAccountActionTriggers", v1.AttrAcntAction{Tenant: "cgrates.org", Account: "dan"}, &ats); err != nil { t.Error(err) } else if len(ats) != 1 || ats[0].ID != *attrs.GroupID || ats[0].ThresholdValue != 50.0 { t.Errorf("Received: %+v", ats) } attrs.ThresholdValue = utils.Float64Pointer(55) // Change the threshold if err := apierRPC.Call("ApierV2.SetAccountActionTriggers", attrs, &reply); err != nil { t.Error(err) } if err := apierRPC.Call("ApierV2.GetAccountActionTriggers", v1.AttrAcntAction{Tenant: "cgrates.org", Account: "dan"}, &ats); err != nil { t.Error(err) } else if len(ats) != 1 || ats[0].ID != *attrs.GroupID || ats[0].ThresholdValue != 55.0 { t.Errorf("Received: %+v", ats) } }
func TesSmFsConfigLoadFromJsonCfg(t *testing.T) { smFsJsnCfg := &SmFsJsonCfg{ Enabled: utils.BoolPointer(true), Create_cdr: utils.BoolPointer(true), Subscribe_park: utils.BoolPointer(true), Connections: &[]*FsConnJsonCfg{ &FsConnJsonCfg{ Server: utils.StringPointer("1.2.3.4:8021"), Password: utils.StringPointer("ClueCon"), Reconnects: utils.IntPointer(5), }, &FsConnJsonCfg{ Server: utils.StringPointer("2.3.4.5:8021"), Password: utils.StringPointer("ClueCon"), Reconnects: utils.IntPointer(5), }, }, } eSmFsConfig := &SmFsConfig{Enabled: true, CreateCdr: true, SubscribePark: true, Connections: []*FsConnConfig{ &FsConnConfig{Server: "1.2.3.4:8021", Password: "******", Reconnects: 5}, &FsConnConfig{Server: "1.2.3.4:8021", Password: "******", Reconnects: 5}, }, } smFsCfg := new(SmFsConfig) if err := smFsCfg.loadFromJsonCfg(smFsJsnCfg); err != nil { t.Error(err) } else if !reflect.DeepEqual(eSmFsConfig, smFsCfg) { t.Error("Received: ", smFsCfg) } }
// Deprecated in rc8, replaced by AddAccountActionTriggers func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string) error { if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } at := &engine.ActionTrigger{ ID: attr.ActionTriggersId, ThresholdType: attr.ThresholdType, ThresholdValue: attr.ThresholdValue, Balance: new(engine.BalanceFilter), Weight: attr.Weight, ActionsID: attr.ActionsId, } if attr.BalanceId != "" { at.Balance.ID = utils.StringPointer(attr.BalanceId) } if attr.BalanceType != "" { at.Balance.Type = utils.StringPointer(attr.BalanceType) } if attr.BalanceDirection != "" { at.Balance.Directions = &utils.StringMap{attr.BalanceDirection: true} } if attr.BalanceDestinationIds != "" { dstIDsMp := utils.StringMapFromSlice(strings.Split(attr.BalanceDestinationIds, utils.INFIELD_SEP)) at.Balance.DestinationIDs = &dstIDsMp } if attr.BalanceRatingSubject != "" { at.Balance.RatingSubject = utils.StringPointer(attr.BalanceRatingSubject) } if attr.BalanceWeight != 0.0 { at.Balance.Weight = utils.Float64Pointer(attr.BalanceWeight) } if balExpiryTime, err := utils.ParseTimeDetectLayout(attr.BalanceExpiryTime, self.Config.DefaultTimezone); err != nil { return utils.NewErrServerError(err) } else { at.Balance.ExpirationDate = &balExpiryTime } if attr.BalanceSharedGroup != "" { at.Balance.SharedGroups = &utils.StringMap{attr.BalanceSharedGroup: true} } acntID := utils.AccountKey(attr.Tenant, attr.Account) _, err := engine.Guardian.Guard(func() (interface{}, error) { acnt, err := self.AccountDb.GetAccount(acntID) if err != nil { return 0, err } acnt.ActionTriggers = append(acnt.ActionTriggers, at) if err = self.AccountDb.SetAccount(acnt); err != nil { return 0, err } return 0, nil }, 0, acntID) if err != nil { return err } *reply = OK return nil }
func TestDfRaterJsonCfg(t *testing.T) { eCfg := &RaterJsonCfg{Enabled: utils.BoolPointer(false), Balancer: utils.StringPointer(""), Cdrstats: utils.StringPointer(""), Historys: utils.StringPointer(""), Pubsubs: utils.StringPointer(""), Users: utils.StringPointer(""), Aliases: utils.StringPointer("")} if cfg, err := dfCgrJsonCfg.RaterJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Errorf("Received: %+v", cfg) } }
func TestDfListenJsonCfg(t *testing.T) { eCfg := &ListenJsonCfg{ Rpc_json: utils.StringPointer("127.0.0.1:2012"), Rpc_gob: utils.StringPointer("127.0.0.1:2013"), Http: utils.StringPointer("127.0.0.1:2080")} if cfg, err := dfCgrJsonCfg.ListenJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", cfg) } }
func testOnStorITCacheActions(t *testing.T) { acts := Actions{ &Action{ Id: "MINI", ActionType: TOPUP_RESET, ExpirationString: UNLIMITED, Weight: 10, Balance: &BalanceFilter{ Type: utils.StringPointer(utils.MONETARY), Uuid: utils.StringPointer(utils.GenUUID()), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), Value: &utils.ValueFormula{Static: 10, Params: make(map[string]interface{})}, Weight: utils.Float64Pointer(10), Disabled: utils.BoolPointer(false), Timings: make([]*RITiming, 0), Blocker: utils.BoolPointer(false), }, }, &Action{ Id: "MINI", ActionType: TOPUP, ExpirationString: UNLIMITED, Weight: 10, Balance: &BalanceFilter{ Type: utils.StringPointer(utils.VOICE), Uuid: utils.StringPointer(utils.GenUUID()), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), Value: &utils.ValueFormula{Static: 100, Params: make(map[string]interface{})}, Weight: utils.Float64Pointer(10), RatingSubject: utils.StringPointer("test"), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT")), Disabled: utils.BoolPointer(false), Timings: make([]*RITiming, 0), Blocker: utils.BoolPointer(false), }, }, } if err := onStor.SetActions(acts[0].Id, acts, utils.NonTransactional); err != nil { t.Error(err) } if _, hasIt := cache.Get(utils.ACTION_PREFIX + acts[0].Id); hasIt { t.Error("Already in cache") } if err := onStor.CacheDataFromDB(utils.ACTION_PREFIX, []string{acts[0].Id}, false); err != nil { t.Error(err) } if itm, hasIt := cache.Get(utils.ACTION_PREFIX + acts[0].Id); !hasIt { t.Error("Did not cache") } else if rcv := itm.(Actions); !reflect.DeepEqual(acts, rcv) { t.Errorf("Expecting: %+v, received: %+v", acts, rcv) } }
func TestDfHistServJsonCfg(t *testing.T) { eCfg := &HistServJsonCfg{ Enabled: utils.BoolPointer(false), History_dir: utils.StringPointer("/var/lib/cgrates/history"), Save_interval: utils.StringPointer("1s"), } if cfg, err := dfCgrJsonCfg.HistServJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", cfg) } }
func (self *ApierV1) SetActions(attrs V1AttrSetActions, reply *string) (err error) { if missing := utils.MissingStructFields(&attrs, []string{"ActionsId", "Actions"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } for _, action := range attrs.Actions { requiredFields := []string{"Identifier", "Weight"} if action.BalanceType != "" { // Add some inter-dependent parameters - if balanceType then we are not talking about simply calling actions requiredFields = append(requiredFields, "Direction", "Units") } if missing := utils.MissingStructFields(action, requiredFields); len(missing) != 0 { return fmt.Errorf("%s:Action:%s:%v", utils.ErrMandatoryIeMissing.Error(), action.Identifier, missing) } } if !attrs.Overwrite { if exists, err := self.RatingDb.HasData(utils.ACTION_PREFIX, attrs.ActionsId); err != nil { return utils.NewErrServerError(err) } else if exists { return utils.ErrExists } } storeActions := make(engine.Actions, len(attrs.Actions)) for idx, apiAct := range attrs.Actions { a := &engine.Action{ Id: attrs.ActionsId, ActionType: apiAct.Identifier, Weight: apiAct.Weight, ExpirationString: apiAct.ExpiryTime, ExtraParameters: apiAct.ExtraParameters, Filter: apiAct.Filter, Balance: &engine.BalanceFilter{ // TODO: update this part Uuid: utils.StringPointer(apiAct.BalanceUuid), ID: utils.StringPointer(apiAct.BalanceId), Type: utils.StringPointer(apiAct.BalanceType), Value: &utils.ValueFormula{Static: apiAct.Units}, Weight: apiAct.BalanceWeight, Directions: utils.StringMapPointer(utils.ParseStringMap(apiAct.Directions)), DestinationIDs: utils.StringMapPointer(utils.ParseStringMap(apiAct.DestinationIds)), RatingSubject: utils.StringPointer(apiAct.RatingSubject), SharedGroups: utils.StringMapPointer(utils.ParseStringMap(apiAct.SharedGroups)), }, } storeActions[idx] = a } if err := self.RatingDb.SetActions(attrs.ActionsId, storeActions, utils.NonTransactional); err != nil { return utils.NewErrServerError(err) } if err = self.RatingDb.CacheDataFromDB(utils.ACTION_PREFIX, []string{attrs.ActionsId}, true); err != nil { utils.NewErrServerError(err) } *reply = OK return nil }
func TestDfResourceLimiterSJsonCfg(t *testing.T) { eCfg := &ResourceLimiterServJsonCfg{ Enabled: utils.BoolPointer(false), Cdrstats_conns: &[]*HaPoolJsonCfg{}, Cache_dump_interval: utils.StringPointer("0s"), Usage_ttl: utils.StringPointer("3h"), } if cfg, err := dfCgrJsonCfg.ResourceLimiterJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", cfg) } }
func TestDfMailerJsonCfg(t *testing.T) { eCfg := &MailerJsonCfg{ Server: utils.StringPointer("localhost"), Auth_user: utils.StringPointer("cgrates"), Auth_password: utils.StringPointer("CGRateS.org"), From_address: utils.StringPointer("*****@*****.**"), } if cfg, err := dfCgrJsonCfg.MailerJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", cfg) } }
func TestLoadAccountActions(t *testing.T) { if len(csvr.accountActions) != 17 { t.Error("Failed to load account actions: ", len(csvr.accountActions)) } aa := csvr.accountActions["vdf:minitsboy"] expected := &Account{ ID: "vdf:minitsboy", UnitCounters: UnitCounters{ utils.VOICE: []*UnitCounter{ &UnitCounter{ CounterType: "*event", Counters: CounterFilters{ &CounterFilter{ Value: 0, Filter: &BalanceFilter{ ID: utils.StringPointer("st0"), Type: utils.StringPointer(utils.VOICE), Directions: utils.StringMapPointer(utils.NewStringMap("*out")), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")), SharedGroups: nil, Categories: nil, TimingIDs: nil, }, }, }, }, }, }, ActionTriggers: csvr.actionsTriggers["STANDARD_TRIGGER"], } // set propper uuid for i, atr := range aa.ActionTriggers { csvr.actionsTriggers["STANDARD_TRIGGER"][i].ID = atr.ID } for i, b := range aa.UnitCounters[utils.VOICE][0].Counters { expected.UnitCounters[utils.VOICE][0].Counters[i].Filter.ID = b.Filter.ID } if !reflect.DeepEqual(aa.UnitCounters[utils.VOICE][0].Counters[0], expected.UnitCounters[utils.VOICE][0].Counters[0]) { t.Errorf("Error loading account action: %+v", utils.ToIJSON(aa.UnitCounters[utils.VOICE][0].Counters[0].Filter)) } // test that it does not overwrite balances existing, err := accountingStorage.GetAccount(aa.ID) if err != nil || len(existing.BalanceMap) != 2 { t.Errorf("The account was not set before load: %+v", existing) } accountingStorage.SetAccount(aa) existing, err = accountingStorage.GetAccount(aa.ID) if err != nil || len(existing.BalanceMap) != 2 { t.Errorf("The set account altered the balances: %+v", existing) } }
func TestLoadActionTriggers(t *testing.T) { if len(csvr.actionsTriggers) != 7 { t.Error("Failed to load action triggers: ", len(csvr.actionsTriggers)) } atr := csvr.actionsTriggers["STANDARD_TRIGGER"][0] expected := &ActionTrigger{ ID: "STANDARD_TRIGGER", UniqueID: "st0", ThresholdType: utils.TRIGGER_MIN_EVENT_COUNTER, ThresholdValue: 10, Balance: &BalanceFilter{ ID: nil, Type: utils.StringPointer(utils.VOICE), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")), Categories: nil, TimingIDs: nil, SharedGroups: nil, Disabled: nil, Blocker: nil, }, Weight: 10, ActionsID: "SOME_1", Executed: false, } if !reflect.DeepEqual(atr, expected) { t.Errorf("Error loading action trigger: %+v", utils.ToIJSON(atr.Balance)) } atr = csvr.actionsTriggers["STANDARD_TRIGGER"][1] expected = &ActionTrigger{ ID: "STANDARD_TRIGGER", UniqueID: "st1", ThresholdType: utils.TRIGGER_MAX_BALANCE, ThresholdValue: 200, Balance: &BalanceFilter{ Type: utils.StringPointer(utils.VOICE), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("GERMANY")), Categories: nil, TimingIDs: nil, SharedGroups: nil, }, Weight: 10, ActionsID: "SOME_2", Executed: false, } if !reflect.DeepEqual(atr, expected) { t.Errorf("Error loading action trigger: %+v", atr) } }
func TestSmKamJsonCfg(t *testing.T) { eCfg := &SmKamJsonCfg{ Enabled: utils.BoolPointer(false), Ha_rater: &[]*HaPoolJsonCfg{ &HaPoolJsonCfg{ Server: utils.StringPointer("internal"), Timeout: utils.StringPointer("100ms"), }}, Ha_cdrs: &[]*HaPoolJsonCfg{ &HaPoolJsonCfg{ Server: utils.StringPointer("internal"), Timeout: utils.StringPointer("100ms"), }}, Create_cdr: utils.BoolPointer(false), Debit_interval: utils.StringPointer("10s"), Min_call_duration: utils.StringPointer("0s"), Max_call_duration: utils.StringPointer("3h"), Connections: &[]*KamConnJsonCfg{ &KamConnJsonCfg{ Evapi_addr: utils.StringPointer("127.0.0.1:8448"), Reconnects: utils.IntPointer(5), }, }, } if cfg, err := dfCgrJsonCfg.SmKamJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", cfg) } }
func TestSmAsteriskJsonCfg(t *testing.T) { eCfg := &SMAsteriskJsonCfg{ Enabled: utils.BoolPointer(false), Sm_generic_conns: &[]*HaPoolJsonCfg{ &HaPoolJsonCfg{ Address: utils.StringPointer(utils.MetaInternal), }}, Session_terminate_subscriber: &HaPoolJsonCfg{Address: utils.StringPointer(utils.MetaInternal)}, Debit_interval: utils.StringPointer("10s"), Min_call_duration: utils.StringPointer("0s"), Max_call_duration: utils.StringPointer("3h"), Asterisk_conns: &[]*AstConnJsonCfg{ &AstConnJsonCfg{ Address: utils.StringPointer("127.0.0.1:8088"), User: utils.StringPointer("cgrates"), Password: utils.StringPointer("CGRateS.org"), Connect_attempts: utils.IntPointer(3), Reconnects: utils.IntPointer(5), }, }, } if cfg, err := dfCgrJsonCfg.SmAsteriskJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", cfg) } }
func GetUB() *Account { uc := &UnitCounter{ Counters: CounterFilters{&CounterFilter{Value: 1}, &CounterFilter{Filter: &BalanceFilter{Weight: utils.Float64Pointer(20), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT"))}}, &CounterFilter{Filter: &BalanceFilter{Weight: utils.Float64Pointer(10), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("RET"))}}}, } at := &ActionTrigger{ ID: "some_uuid", ThresholdValue: 100.0, Balance: &BalanceFilter{ Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT")), }, Weight: 10.0, ActionsID: "Commando", } var zeroTime time.Time zeroTime = zeroTime.UTC() // for deep equal to find location ub := &Account{ ID: "rif", AllowNegative: true, BalanceMap: map[string]Balances{utils.SMS: Balances{&Balance{Value: 14, ExpirationDate: zeroTime}}, utils.DATA: Balances{&Balance{Value: 1024, ExpirationDate: zeroTime}}, utils.VOICE: Balances{&Balance{Weight: 20, DestinationIDs: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIDs: utils.NewStringMap("RET")}}}, UnitCounters: UnitCounters{utils.SMS: []*UnitCounter{uc, uc}}, ActionTriggers: ActionTriggers{at, at, at}, } return ub }
func TestTpActionTriggers(t *testing.T) { var atrs engine.ActionTriggers if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{}}, &atrs); err != nil { t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error()) } else if len(atrs) != 9 { t.Errorf("Calling v1.GetActionTriggers got: %v", atrs) } var reply string if err := tpRPC.Call("ApierV1.SetActionTrigger", v1.AttrSetActionTrigger{ GroupID: "TestATR", UniqueID: "Unique atr id", BalanceID: utils.StringPointer("BID1"), }, &reply); err != nil { t.Error("Got error on ApierV1.SetActionTrigger: ", err.Error()) } else if reply != utils.OK { t.Errorf("Calling v1.SetActionTrigger got: %v", reply) } if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{}}, &atrs); err != nil { t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error()) } else if len(atrs) != 10 { t.Errorf("Calling v1.GetActionTriggers got: %v", atrs) } if err := tpRPC.Call("ApierV1.GetActionTriggers", v1.AttrGetActionTriggers{GroupIDs: []string{"TestATR"}}, &atrs); err != nil { t.Error("Got error on ApierV1.GetActionTriggers: ", err.Error()) } else if len(atrs) != 1 { t.Errorf("Calling v1.GetActionTriggers got: %v", atrs) } if atrs[0].ID != "TestATR" || atrs[0].UniqueID != "Unique atr id" || *atrs[0].Balance.ID != "BID1" { t.Error("Wrong action trigger set: ", utils.ToIJSON(atrs[0])) } }
func TestBalanceMatchFilterId(t *testing.T) { mb1 := &Balance{ID: "T1", Weight: 2, precision: 2, RatingSubject: "2", DestinationIDs: utils.NewStringMap("NAT")} mb2 := &BalanceFilter{ID: utils.StringPointer("T1"), Weight: utils.Float64Pointer(1), RatingSubject: utils.StringPointer("1"), DestinationIDs: nil} if !mb1.MatchFilter(mb2, false) { t.Errorf("Match filter failure: %+v == %+v", mb1, mb2) } }
func TestBalanceMatchFilterDiffId(t *testing.T) { mb1 := &Balance{ID: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationIDs: utils.StringMap{}} mb2 := &BalanceFilter{ID: utils.StringPointer("T2"), Weight: utils.Float64Pointer(1), RatingSubject: utils.StringPointer("1"), DestinationIDs: nil} if mb1.MatchFilter(mb2, false) { t.Errorf("Match filter failure: %+v != %+v", mb1, mb2) } }
func (self *ApierV1) RemoveBalances(attr *utils.AttrSetBalance, reply *string) error { if missing := utils.MissingStructFields(attr, []string{"Tenant", "Account", "BalanceType"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } var expTime *time.Time if attr.ExpiryTime != nil { expTimeVal, err := utils.ParseTimeDetectLayout(*attr.ExpiryTime, self.Config.DefaultTimezone) if err != nil { *reply = err.Error() return err } expTime = &expTimeVal } accID := utils.AccountKey(attr.Tenant, attr.Account) if _, err := self.AccountDb.GetAccount(accID); err != nil { return utils.ErrNotFound } at := &engine.ActionTiming{} at.SetAccountIDs(utils.StringMap{accID: true}) a := &engine.Action{ ActionType: engine.REMOVE_BALANCE, Balance: &engine.BalanceFilter{ Uuid: attr.BalanceUUID, ID: attr.BalanceID, Type: utils.StringPointer(attr.BalanceType), ExpirationDate: expTime, RatingSubject: attr.RatingSubject, Weight: attr.Weight, Blocker: attr.Blocker, Disabled: attr.Disabled, }, } if attr.Value != nil { a.Balance.Value = &utils.ValueFormula{Static: *attr.Value} } if attr.Directions != nil { a.Balance.Directions = utils.StringMapPointer(utils.ParseStringMap(*attr.Directions)) } if attr.DestinationIds != nil { a.Balance.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(*attr.DestinationIds)) } if attr.Categories != nil { a.Balance.Categories = utils.StringMapPointer(utils.ParseStringMap(*attr.Categories)) } if attr.SharedGroups != nil { a.Balance.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(*attr.SharedGroups)) } if attr.TimingIds != nil { a.Balance.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(*attr.TimingIds)) } at.SetActions(engine.Actions{a}) if err := at.Execute(); err != nil { *reply = err.Error() return err } *reply = OK return nil }
func TestSmGenericJsonCfg(t *testing.T) { eCfg := &SmGenericJsonCfg{ Enabled: utils.BoolPointer(false), Listen_bijson: utils.StringPointer("127.0.0.1:2014"), Rals_conns: &[]*HaPoolJsonCfg{ &HaPoolJsonCfg{ Address: utils.StringPointer(utils.MetaInternal), }}, Cdrs_conns: &[]*HaPoolJsonCfg{ &HaPoolJsonCfg{ Address: utils.StringPointer(utils.MetaInternal), }}, Smg_replication_conns: &[]*HaPoolJsonCfg{}, Debit_interval: utils.StringPointer("0s"), Min_call_duration: utils.StringPointer("0s"), Max_call_duration: utils.StringPointer("3h"), Session_ttl: utils.StringPointer("0s"), Session_indexes: utils.StringSlicePointer([]string{}), } if cfg, err := dfCgrJsonCfg.SmGenericJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", cfg) } }
func TestDfCdrsJsonCfg(t *testing.T) { eCfg := &CdrsJsonCfg{ Enabled: utils.BoolPointer(false), Extra_fields: utils.StringSlicePointer([]string{}), Store_cdrs: utils.BoolPointer(true), Rater: utils.StringPointer("internal"), Pubsubs: utils.StringPointer(""), Users: utils.StringPointer(""), Aliases: utils.StringPointer(""), Cdrstats: utils.StringPointer(""), Cdr_replication: &[]*CdrReplicationJsonCfg{}, } if cfg, err := dfCgrJsonCfg.CdrsJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Errorf("Received: %+v", *cfg) } }
func TestDfRalsJsonCfg(t *testing.T) { eCfg := &RalsJsonCfg{Enabled: utils.BoolPointer(false), Balancer: utils.StringPointer(""), Cdrstats_conns: &[]*HaPoolJsonCfg{}, Historys_conns: &[]*HaPoolJsonCfg{}, Pubsubs_conns: &[]*HaPoolJsonCfg{}, Users_conns: &[]*HaPoolJsonCfg{}, Aliases_conns: &[]*HaPoolJsonCfg{}, Rp_subject_prefix_matching: utils.BoolPointer(false), Lcr_subject_prefix_matching: utils.BoolPointer(false)} if cfg, err := dfCgrJsonCfg.RalsJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Errorf("Received: %+v", cfg) } }
func TestDfCdrStatsJsonCfg(t *testing.T) { eCfg := &CdrStatsJsonCfg{ Enabled: utils.BoolPointer(false), Save_Interval: utils.StringPointer("1m"), } if cfg, err := dfCgrJsonCfg.CdrStatsJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", *cfg) } }
func TestSmAsteriskJsonCfg(t *testing.T) { eCfg := &SMAsteriskJsonCfg{ Enabled: utils.BoolPointer(false), Create_cdr: utils.BoolPointer(false), Asterisk_conns: &[]*AstConnJsonCfg{ &AstConnJsonCfg{ Address: utils.StringPointer("127.0.0.1:8088"), User: utils.StringPointer("cgrates"), Password: utils.StringPointer("CGRateS.org"), Connect_attempts: utils.IntPointer(3), Reconnects: utils.IntPointer(5), }, }, } if cfg, err := dfCgrJsonCfg.SmAsteriskJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { t.Error("Received: ", cfg) } }
func TestDfGeneralJsonCfg(t *testing.T) { eCfg := &GeneralJsonCfg{ Http_skip_tls_verify: utils.BoolPointer(false), Rounding_decimals: utils.IntPointer(10), Dbdata_encoding: utils.StringPointer("msgpack"), Tpexport_dir: utils.StringPointer("/var/log/cgrates/tpe"), Http_failed_dir: utils.StringPointer("/var/log/cgrates/http_failed"), Default_reqtype: utils.StringPointer(utils.META_RATED), Default_category: utils.StringPointer("call"), Default_tenant: utils.StringPointer("cgrates.org"), Default_subject: utils.StringPointer("cgrates"), Default_timezone: utils.StringPointer("Local"), Connect_attempts: utils.IntPointer(3), Reconnects: utils.IntPointer(-1), Response_cache_ttl: utils.StringPointer("3s"), Internal_ttl: utils.StringPointer("2m")} if gCfg, err := dfCgrJsonCfg.GeneralJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, gCfg) { t.Error("Received: ", gCfg) } }
// Create counters for all triggered actions func (acc *Account) InitCounters() { oldUcs := acc.UnitCounters acc.UnitCounters = make(UnitCounters) ucTempMap := make(map[string]*UnitCounter) for _, at := range acc.ActionTriggers { //log.Print("AT: ", utils.ToJSON(at)) if !strings.Contains(at.ThresholdType, "counter") { continue } ct := utils.COUNTER_EVENT //default if strings.Contains(at.ThresholdType, "balance") { ct = utils.COUNTER_BALANCE } uc, exists := ucTempMap[at.Balance.GetType()+ct] //log.Print("CT: ", at.Balance.GetType()+ct) if !exists { uc = &UnitCounter{ CounterType: ct, } ucTempMap[at.Balance.GetType()+ct] = uc uc.Counters = make(CounterFilters, 0) acc.UnitCounters[at.Balance.GetType()] = append(acc.UnitCounters[at.Balance.GetType()], uc) } c := &CounterFilter{Filter: at.Balance.Clone()} if (c.Filter.ID == nil || *c.Filter.ID == "") && at.UniqueID != "" { c.Filter.ID = utils.StringPointer(at.UniqueID) } //log.Print("C: ", utils.ToJSON(c)) if !uc.Counters.HasCounter(c) { uc.Counters = append(uc.Counters, c) } } // copy old counter values for key, counters := range acc.UnitCounters { oldCounters, found := oldUcs[key] if !found { continue } for _, uc := range counters { for _, oldUc := range oldCounters { if uc.CopyCounterValues(oldUc) { break } } } } if len(acc.UnitCounters) == 0 { acc.UnitCounters = nil // leave it nil if empty } }
func TestBalanceMatchActionTriggerId(t *testing.T) { at := &ActionTrigger{Balance: &BalanceFilter{ID: utils.StringPointer("test")}} b := &Balance{ID: "test"} if !b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } b.ID = "test1" if b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } b.ID = "" if b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } b.ID = "test" at.Balance.ID = nil if !b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } }
func TestApierV2itAddBalance(t *testing.T) { attrs := &utils.AttrSetBalance{ Tenant: "cgrates.org", Account: "dan", BalanceType: utils.MONETARY, BalanceID: utils.StringPointer(utils.META_DEFAULT), Value: utils.Float64Pointer(5.0), Weight: utils.Float64Pointer(10.0), } var reply string if err := apierRPC.Call("ApierV2.SetBalance", attrs, &reply); err != nil { t.Fatal(err) } var acnt engine.Account if err := apierRPC.Call("ApierV2.GetAccount", &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "dan"}, &acnt); err != nil { t.Error(err) } else if acnt.BalanceMap[utils.MONETARY][0].Value != 5.0 { t.Errorf("Unexpected balance received: %+v", acnt.BalanceMap[utils.MONETARY][0]) } }
func TestBalanceMatchActionTriggerRatingSubject(t *testing.T) { at := &ActionTrigger{Balance: &BalanceFilter{RatingSubject: utils.StringPointer("test")}} b := &Balance{RatingSubject: "test"} if !b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } b.RatingSubject = "test1" if b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } b.RatingSubject = "" if b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } b.RatingSubject = "test" at.Balance.RatingSubject = nil if !b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } }