mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-15 21:29:52 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -523,14 +523,14 @@ func (self *ApierV1) SetActions(attrs utils.AttrSetActions, reply *string) error
|
||||
}
|
||||
|
||||
a := &engine.Action{
|
||||
Id: utils.GenUUID(),
|
||||
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(utils.GenUUID()),
|
||||
Uuid: utils.StringPointer(apiAct.BalanceUuid),
|
||||
ID: utils.StringPointer(apiAct.BalanceId),
|
||||
Type: utils.StringPointer(apiAct.BalanceType),
|
||||
Value: vf,
|
||||
@@ -562,7 +562,8 @@ func (self *ApierV1) GetActions(actsId string, reply *[]*utils.TPAction) error {
|
||||
return utils.NewErrServerError(err)
|
||||
}
|
||||
for _, engAct := range engActs {
|
||||
act := &utils.TPAction{Identifier: engAct.ActionType,
|
||||
act := &utils.TPAction{
|
||||
Identifier: engAct.ActionType,
|
||||
ExpiryTime: engAct.ExpirationString,
|
||||
ExtraParameters: engAct.ExtraParameters,
|
||||
Filter: engAct.Filter,
|
||||
@@ -1063,3 +1064,63 @@ func (self *ApierV1) GetLoadHistory(attrs utils.Paginator, reply *[]*engine.Load
|
||||
*reply = loadHist[offset:nrItems]
|
||||
return nil
|
||||
}
|
||||
|
||||
type AttrRemActions struct {
|
||||
ActionIDs []string
|
||||
}
|
||||
|
||||
func (self *ApierV1) RemActions(attr AttrRemActions, reply *string) error {
|
||||
if attr.ActionIDs == nil {
|
||||
err := utils.ErrNotFound
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
stringMap := utils.NewStringMap(attr.ActionIDs...)
|
||||
keys, err := self.RatingDb.GetKeysForPrefix(utils.ACTION_TRIGGER_PREFIX, true)
|
||||
if err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
for _, key := range keys {
|
||||
getAttrs, err := self.RatingDb.GetActionTriggers(key[len(utils.ACTION_TRIGGER_PREFIX):])
|
||||
if err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
for _, atr := range getAttrs {
|
||||
if _, found := stringMap[atr.ActionsID]; found {
|
||||
// found action trigger referencing action; abort
|
||||
err := fmt.Errorf("action %s refenced by action trigger %s", atr.ActionsID, atr.ID)
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
allAplsMap, err := self.RatingDb.GetAllActionPlans()
|
||||
if err != nil && err != utils.ErrNotFound {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
for _, apl := range allAplsMap {
|
||||
for _, atm := range apl.ActionTimings {
|
||||
if _, found := stringMap[atm.ActionsID]; found {
|
||||
err := fmt.Errorf("action %s refenced by action plan %s", atm.ActionsID, apl.Id)
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for _, aID := range attr.ActionIDs {
|
||||
if err := self.RatingDb.RemoveActions(aID); err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := self.RatingDb.CacheRatingPrefixes(utils.ACTION_PREFIX); err != nil {
|
||||
*reply = err.Error()
|
||||
return err
|
||||
}
|
||||
*reply = utils.OK
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1297,7 +1297,7 @@ func TestApierResetDataAfterLoadFromFolder(t *testing.T) {
|
||||
if rcvStats.Destinations != 5 ||
|
||||
rcvStats.RatingPlans != 5 ||
|
||||
rcvStats.RatingProfiles != 5 ||
|
||||
rcvStats.Actions != 10 ||
|
||||
rcvStats.Actions != 11 ||
|
||||
rcvStats.DerivedChargers != 3 {
|
||||
t.Errorf("Calling ApierV1.GetCacheStats received: %+v", rcvStats)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func (self *ApierV2) GetAccounts(attr utils.AttrGetAccounts, reply *[]*engine.Ac
|
||||
var accountKeys []string
|
||||
var err error
|
||||
if len(attr.AccountIds) == 0 {
|
||||
if accountKeys, err = self.AccountDb.GetKeysForPrefix(utils.ACCOUNT_PREFIX+utils.ConcatenatedKey(attr.Tenant), true); err != nil {
|
||||
if accountKeys, err = self.AccountDb.GetKeysForPrefix(utils.ACCOUNT_PREFIX+attr.Tenant, true); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -21,6 +21,7 @@ package v2
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
@@ -263,3 +264,58 @@ func (self *ApierV2) LoadTariffPlanFromFolder(attrs utils.AttrLoadTpFromFolder,
|
||||
*reply = *li
|
||||
return nil
|
||||
}
|
||||
|
||||
type AttrGetActions struct {
|
||||
ActionIDs []string
|
||||
Offset int // Set the item offset
|
||||
Limit int // Limit number of items retrieved
|
||||
}
|
||||
|
||||
// Retrieves actions attached to specific ActionsId within cache
|
||||
func (self *ApierV2) GetActions(attr AttrGetActions, reply *map[string]engine.Actions) error {
|
||||
var actionKeys []string
|
||||
var err error
|
||||
if len(attr.ActionIDs) == 0 {
|
||||
if actionKeys, err = self.AccountDb.GetKeysForPrefix(utils.ACTION_PREFIX, false); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
for _, accID := range attr.ActionIDs {
|
||||
if len(accID) == 0 { // Source of error returned from redis (key not found)
|
||||
continue
|
||||
}
|
||||
actionKeys = append(actionKeys, utils.ACCOUNT_PREFIX+accID)
|
||||
}
|
||||
}
|
||||
if len(actionKeys) == 0 {
|
||||
return nil
|
||||
}
|
||||
if attr.Offset > len(actionKeys) {
|
||||
attr.Offset = len(actionKeys)
|
||||
}
|
||||
if attr.Offset < 0 {
|
||||
attr.Offset = 0
|
||||
}
|
||||
var limitedActions []string
|
||||
if attr.Limit != 0 {
|
||||
max := math.Min(float64(attr.Offset+attr.Limit), float64(len(actionKeys)))
|
||||
limitedActions = actionKeys[attr.Offset:int(max)]
|
||||
} else {
|
||||
limitedActions = actionKeys[attr.Offset:]
|
||||
}
|
||||
retActions := make(map[string]engine.Actions)
|
||||
for _, accKey := range limitedActions {
|
||||
key := accKey[len(utils.ACTION_PREFIX):]
|
||||
acts, err := self.RatingDb.GetActions(key, false)
|
||||
if err != nil {
|
||||
return utils.NewErrServerError(err)
|
||||
}
|
||||
if len(acts) > 0 {
|
||||
retActions[key] = acts
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
*reply = retActions
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
_ "net/http/pprof"
|
||||
// _ "net/http/pprof"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
|
||||
@@ -18,7 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
package console
|
||||
|
||||
import "github.com/cgrates/cgrates/utils"
|
||||
import (
|
||||
"github.com/cgrates/cgrates/apier/v2"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
)
|
||||
|
||||
func init() {
|
||||
c := &CmdGetActions{
|
||||
@@ -33,7 +36,7 @@ func init() {
|
||||
type CmdGetActions struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams *StringWrapper
|
||||
rpcParams *v2.AttrGetActions
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
@@ -47,7 +50,7 @@ func (self *CmdGetActions) RpcMethod() string {
|
||||
|
||||
func (self *CmdGetActions) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &StringWrapper{}
|
||||
self.rpcParams = &v2.AttrGetActions{}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
@@ -57,6 +60,6 @@ func (self *CmdGetActions) PostprocessRpcParams() error {
|
||||
}
|
||||
|
||||
func (self *CmdGetActions) RpcResult() interface{} {
|
||||
a := make([]*utils.TPAction, 0)
|
||||
a := make(map[string]engine.Actions, 0)
|
||||
return &a
|
||||
}
|
||||
|
||||
62
console/actions_remove.go
Normal file
62
console/actions_remove.go
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Real-time Charging System for Telecom & ISP environments
|
||||
Copyright (C) 2012-2015 ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package console
|
||||
|
||||
import "github.com/cgrates/cgrates/apier/v1"
|
||||
|
||||
func init() {
|
||||
c := &CmdRemoveActions{
|
||||
name: "actions_remove",
|
||||
rpcMethod: "ApierV1.RemActions",
|
||||
}
|
||||
commands[c.Name()] = c
|
||||
c.CommandExecuter = &CommandExecuter{c}
|
||||
}
|
||||
|
||||
// Commander implementation
|
||||
type CmdRemoveActions struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams *v1.AttrRemActions
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
func (self *CmdRemoveActions) Name() string {
|
||||
return self.name
|
||||
}
|
||||
|
||||
func (self *CmdRemoveActions) RpcMethod() string {
|
||||
return self.rpcMethod
|
||||
}
|
||||
|
||||
func (self *CmdRemoveActions) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &v1.AttrRemActions{}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
|
||||
func (self *CmdRemoveActions) PostprocessRpcParams() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *CmdRemoveActions) RpcResult() interface{} {
|
||||
var s string
|
||||
return &s
|
||||
}
|
||||
@@ -9,4 +9,5 @@ cgrates.org,1010,TEST_DATA_r,,true,
|
||||
cgrates.org,1011,TEST_VOICE,,,
|
||||
cgrates.org,1012,PREPAID_10,,,
|
||||
cgrates.org,1013,TEST_NEG,,,
|
||||
cgrates.org,1014,TEST_RPC,,,
|
||||
cgrates.org,1014,TEST_RPC,,,
|
||||
cgrates.org,1015,,,,
|
||||
|
||||
|
@@ -10,3 +10,5 @@ TOPUP_DATA_r,*topup,,,,*data,*out,,DATA_DEST,datar,,*unlimited,,50000000000,10,f
|
||||
TOPUP_VOICE,*topup,,,,*voice,*out,,GERMANY_MOBILE,,,*unlimited,,50000,10,false,false,10
|
||||
TOPUP_NEG,*topup,,,,*voice,*out,,GERMANY;!GERMANY_MOBILE,*zero1m,,*unlimited,,100,10,false,false,10
|
||||
RPC,*cgr_rpc,"{""Address"": ""localhost:2013"",""Transport"":""*gob"",""Method"":""ApierV2.SetAccount"",""Attempts"":1,""Async"" :false,""Params"":{""Account"":""rpc"",""Tenant"":""cgrates.org""}}",,,,,,,,,,,,,,,
|
||||
DID,*debit,,,,*monetary,*out,,*any,,,*unlimited,*any,"{""Method"":""*incremental"",""Params"":{""Units"":1, ""Interval"":""month"",""Increment"":""day""}}",10.0,,,10.0
|
||||
DID,*cdrlog,"{""action"":""^DID"",""prev_balance"":""BalanceValue""}",,,*monetary,*out,,*any,,,*unlimited,,,10.0,,,10.0
|
||||
|
||||
|
@@ -833,7 +833,7 @@ func TestLoadActions(t *testing.T) {
|
||||
as1 := csvr.actions["MINI"]
|
||||
expected := []*Action{
|
||||
&Action{
|
||||
Id: "MINI0",
|
||||
Id: "MINI",
|
||||
ActionType: TOPUP_RESET,
|
||||
ExpirationString: UNLIMITED,
|
||||
ExtraParameters: "",
|
||||
@@ -853,7 +853,7 @@ func TestLoadActions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
&Action{
|
||||
Id: "MINI1",
|
||||
Id: "MINI",
|
||||
ActionType: TOPUP,
|
||||
ExpirationString: UNLIMITED,
|
||||
ExtraParameters: "",
|
||||
@@ -880,7 +880,7 @@ func TestLoadActions(t *testing.T) {
|
||||
as2 := csvr.actions["SHARED"]
|
||||
expected = []*Action{
|
||||
&Action{
|
||||
Id: "SHARED0",
|
||||
Id: "SHARED",
|
||||
ActionType: TOPUP,
|
||||
ExpirationString: UNLIMITED,
|
||||
Weight: 10,
|
||||
@@ -905,7 +905,7 @@ func TestLoadActions(t *testing.T) {
|
||||
as3 := csvr.actions["DEFEE"]
|
||||
expected = []*Action{
|
||||
&Action{
|
||||
Id: "DEFEE0",
|
||||
Id: "DEFEE",
|
||||
ActionType: CDRLOG,
|
||||
ExtraParameters: `{"Category":"^ddi","MediationRunId":"^did_run"}`,
|
||||
Weight: 10,
|
||||
|
||||
@@ -59,6 +59,7 @@ type RatingStorage interface {
|
||||
SetDerivedChargers(string, *utils.DerivedChargers) error
|
||||
GetActions(string, bool) (Actions, error)
|
||||
SetActions(string, Actions) error
|
||||
RemoveActions(string) error
|
||||
GetSharedGroup(string, bool) (*SharedGroup, error)
|
||||
SetSharedGroup(*SharedGroup) error
|
||||
GetActionTriggers(string) (ActionTriggers, error)
|
||||
@@ -204,6 +205,7 @@ func NewCodecMsgpackMarshaler() *CodecMsgpackMarshaler {
|
||||
cmm := &CodecMsgpackMarshaler{new(codec.MsgpackHandle)}
|
||||
mh := cmm.mh
|
||||
mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
|
||||
mh.RawToString = true
|
||||
return cmm
|
||||
}
|
||||
|
||||
|
||||
@@ -469,6 +469,13 @@ func (ms *MapStorage) SetActions(key string, as Actions) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) RemoveActions(key string) (err error) {
|
||||
ms.mu.Lock()
|
||||
defer ms.mu.Unlock()
|
||||
delete(ms.dict, utils.ACTION_PREFIX+key)
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) {
|
||||
ms.mu.RLock()
|
||||
defer ms.mu.RUnlock()
|
||||
|
||||
@@ -916,6 +916,10 @@ func (ms *MongoStorage) SetActions(key string, as Actions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) RemoveActions(key string) error {
|
||||
return ms.db.C(colAct).Remove(bson.M{"key": key})
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) {
|
||||
if !skipCache {
|
||||
if x, err := cache2go.Get(utils.SHARED_GROUP_PREFIX + key); err == nil {
|
||||
|
||||
@@ -590,6 +590,11 @@ func (rs *RedisStorage) SetActions(key string, as Actions) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) RemoveActions(key string) (err error) {
|
||||
err = rs.db.Cmd("DEL", utils.ACTION_PREFIX+key).Err
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) {
|
||||
key = utils.SHARED_GROUP_PREFIX + key
|
||||
if !skipCache {
|
||||
|
||||
@@ -514,7 +514,7 @@ func (tpr *TpReader) LoadActions() (err error) {
|
||||
}
|
||||
}
|
||||
acts[idx] = &Action{
|
||||
Id: tag + strconv.Itoa(idx),
|
||||
Id: tag,
|
||||
ActionType: tpact.Identifier,
|
||||
//BalanceType: tpact.BalanceType,
|
||||
Weight: tpact.Weight,
|
||||
@@ -990,7 +990,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
|
||||
}
|
||||
}
|
||||
acts[idx] = &Action{
|
||||
Id: tag + strconv.Itoa(idx),
|
||||
Id: tag,
|
||||
ActionType: tpact.Identifier,
|
||||
//BalanceType: tpact.BalanceType,
|
||||
Weight: tpact.Weight,
|
||||
@@ -1338,7 +1338,7 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
|
||||
}
|
||||
}
|
||||
acts[idx] = &Action{
|
||||
Id: tag + strconv.Itoa(idx),
|
||||
Id: tag,
|
||||
ActionType: tpact.Identifier,
|
||||
//BalanceType: tpact.BalanceType,
|
||||
Weight: tpact.Weight,
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/apier/v1"
|
||||
"github.com/cgrates/cgrates/apier/v2"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
@@ -239,3 +240,128 @@ func TestTpExecuteActionCgrRpc(t *testing.T) {
|
||||
t.Error("Got error on ApierV2.GetAccount: ", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTpCreateExecuteActionMatch(t *testing.T) {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
var reply string
|
||||
if err := tpRPC.Call("ApierV2.SetActions", utils.AttrSetActions{
|
||||
ActionsId: "PAYMENT_2056bd2fe137082970f97102b64e42fd",
|
||||
Actions: []*utils.TPAction{
|
||||
&utils.TPAction{
|
||||
BalanceType: "*monetary",
|
||||
Directions: "*out",
|
||||
Identifier: "*topup",
|
||||
RatingSubject: "",
|
||||
Units: "10.500000",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
}, &reply); err != nil {
|
||||
t.Error("Got error on ApierV2.SetActions: ", err.Error())
|
||||
} else if reply != utils.OK {
|
||||
t.Errorf("Calling ApierV2.SetActions got reply: %s", reply)
|
||||
}
|
||||
if err := tpRPC.Call("ApierV2.ExecuteAction", utils.AttrExecuteAction{
|
||||
Tenant: "cgrates.org",
|
||||
Account: "1015",
|
||||
ActionsId: "PAYMENT_2056bd2fe137082970f97102b64e42fd",
|
||||
}, &reply); err != nil {
|
||||
t.Error("Got error on ApierV2.ExecuteAction: ", err.Error())
|
||||
} else if reply != utils.OK {
|
||||
t.Errorf("Calling ExecuteAction got reply: %s", reply)
|
||||
}
|
||||
if err := tpRPC.Call("ApierV2.ExecuteAction", utils.AttrExecuteAction{
|
||||
Tenant: "cgrates.org",
|
||||
Account: "1015",
|
||||
ActionsId: "PAYMENT_2056bd2fe137082970f97102b64e42fd",
|
||||
}, &reply); err != nil {
|
||||
t.Error("Got error on ApierV2.ExecuteAction: ", err.Error())
|
||||
} else if reply != utils.OK {
|
||||
t.Errorf("Calling ExecuteAction got reply: %s", reply)
|
||||
}
|
||||
var acnt engine.Account
|
||||
attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1015"}
|
||||
if err := tpRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error("Got error on ApierV2.GetAccount: ", err.Error())
|
||||
}
|
||||
if len(acnt.BalanceMap) != 1 ||
|
||||
len(acnt.BalanceMap[utils.MONETARY]) != 1 ||
|
||||
acnt.BalanceMap[utils.MONETARY].GetTotalValue() != 21 {
|
||||
t.Error("error matching previous created balance: ", utils.ToIJSON(acnt.BalanceMap))
|
||||
}
|
||||
}
|
||||
|
||||
func TestTpSetRemActions(t *testing.T) {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
var reply string
|
||||
if err := tpRPC.Call("ApierV2.SetActions", utils.AttrSetActions{
|
||||
ActionsId: "TO_BE_DELETED",
|
||||
Actions: []*utils.TPAction{
|
||||
&utils.TPAction{
|
||||
BalanceType: "*monetary",
|
||||
Directions: "*out",
|
||||
Identifier: "*topup",
|
||||
RatingSubject: "",
|
||||
Units: "10.500000",
|
||||
Weight: 10,
|
||||
},
|
||||
},
|
||||
}, &reply); err != nil {
|
||||
t.Error("Got error on ApierV2.SetActions: ", err.Error())
|
||||
} else if reply != utils.OK {
|
||||
t.Errorf("Calling ApierV2.SetActions got reply: %s", reply)
|
||||
}
|
||||
actionsMap := make(map[string]engine.Actions)
|
||||
if err := tpRPC.Call("ApierV2.GetActions", v2.AttrGetActions{
|
||||
ActionIDs: []string{"PAYMENT_2056bd2fe137082970f97102b64e42fd"},
|
||||
}, &actionsMap); err != nil {
|
||||
t.Error("Got error on ApierV2.GetActions: ", err.Error())
|
||||
} else if len(actionsMap) != 1 {
|
||||
t.Errorf("Calling ApierV2.GetActions got reply: %s", utils.ToIJSON(actionsMap))
|
||||
}
|
||||
if err := tpRPC.Call("ApierV2.RemActions", v1.AttrRemActions{
|
||||
ActionIDs: []string{"PAYMENT_2056bd2fe137082970f97102b64e42fd"},
|
||||
}, &reply); err != nil {
|
||||
t.Error("Got error on ApierV2.RemActions: ", err.Error())
|
||||
} else if reply != utils.OK {
|
||||
t.Errorf("Calling ApierV2.RemActions got reply: %s", reply)
|
||||
}
|
||||
if err := tpRPC.Call("ApierV2.GetActions", v2.AttrGetActions{
|
||||
ActionIDs: []string{"PAYMENT_2056bd2fe137082970f97102b64e42fd"},
|
||||
}, &actionsMap); err == nil {
|
||||
t.Error("no error on ApierV2.GetActions: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTpRemActionsRefenced(t *testing.T) {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
actionsMap := make(map[string]engine.Actions)
|
||||
if err := tpRPC.Call("ApierV2.GetActions", v2.AttrGetActions{
|
||||
ActionIDs: []string{"TOPUP_VOICE"},
|
||||
}, &actionsMap); err != nil {
|
||||
t.Error("Got error on ApierV2.GetActions: ", err.Error())
|
||||
} else if len(actionsMap) != 1 {
|
||||
t.Errorf("Calling ApierV2.GetActions got reply: %s", utils.ToIJSON(actionsMap))
|
||||
}
|
||||
var reply string
|
||||
if err := tpRPC.Call("ApierV2.RemActions", v1.AttrRemActions{
|
||||
ActionIDs: []string{"TOPUP_VOICE"},
|
||||
}, &reply); err == nil {
|
||||
t.Error("No error on ApierV2.RemActions: ", err.Error())
|
||||
} else if reply == utils.OK {
|
||||
t.Errorf("Calling ApierV2.RemActions got reply: %s", reply)
|
||||
}
|
||||
if err := tpRPC.Call("ApierV2.GetActions", v2.AttrGetActions{
|
||||
ActionIDs: []string{"TOPUP_VOICE"},
|
||||
}, &actionsMap); err != nil {
|
||||
t.Error("Got error on ApierV2.GetActions: ", err.Error())
|
||||
} else if len(actionsMap) != 1 {
|
||||
t.Errorf("Calling ApierV2.GetActions got reply: %s", utils.ToIJSON(actionsMap))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,6 +212,12 @@ func TestSMGDataLastUsedMultipleData(t *testing.T) {
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
aSessions := make([]*ActiveSession, 0)
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1048576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
@@ -238,6 +244,11 @@ func TestSMGDataLastUsedMultipleData(t *testing.T) {
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1068576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
@@ -264,7 +275,11 @@ func TestSMGDataLastUsedMultipleData(t *testing.T) {
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1088576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
@@ -291,6 +306,11 @@ func TestSMGDataLastUsedMultipleData(t *testing.T) {
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1108576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
@@ -317,7 +337,11 @@ func TestSMGDataLastUsedMultipleData(t *testing.T) {
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1128576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
@@ -341,6 +365,11 @@ func TestSMGDataLastUsedMultipleData(t *testing.T) {
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 0 {
|
||||
t.Errorf("wrong active sessions: %+v", aSessions)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSMGDataDerivedChargingNoCredit(t *testing.T) {
|
||||
@@ -474,6 +503,12 @@ func TestSMGDataTTLExpiredMultiUpdates(t *testing.T) {
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
aSessions := make([]*ActiveSession, 0)
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1048576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
@@ -509,4 +544,410 @@ func TestSMGDataTTLExpiredMultiUpdates(t *testing.T) {
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 0 {
|
||||
t.Errorf("wrong active sessions: %+v", aSessions)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSMGDataMultipleDataNoUsage(t *testing.T) {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
var acnt *engine.Account
|
||||
attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1010"}
|
||||
eAcntVal := 49997767680.000000
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
smgEv := SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.SETUP_TIME: "2016-01-05 18:30:49",
|
||||
utils.ANSWER_TIME: "2016-01-05 18:31:05",
|
||||
utils.USAGE: "1048576",
|
||||
}
|
||||
var maxUsage float64
|
||||
if err := smgRPC.Call("SMGenericV1.SessionStart", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 1054720
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
aSessions := make([]*ActiveSession, 0)
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1048576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.USAGE: "1048576",
|
||||
utils.LastUsed: "0",
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.SessionUpdate", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 0
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1048576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.USAGE: "1048576",
|
||||
utils.LastUsed: "0",
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.SessionUpdate", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 0
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1048576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.USAGE: "1048576",
|
||||
utils.LastUsed: "0",
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.SessionUpdate", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 0
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1048576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.USAGE: "1048576",
|
||||
utils.LastUsed: "0",
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.SessionUpdate", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 0
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1048576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.LastUsed: "0",
|
||||
}
|
||||
var rpl string
|
||||
if err = smgRPC.Call("SMGenericV1.SessionEnd", smgEv, &rpl); err != nil || rpl != utils.OK {
|
||||
t.Error(err)
|
||||
}
|
||||
eAcntVal = 49997767680.000000 // refunded
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 0 {
|
||||
t.Errorf("wrong active sessions: %+v", aSessions)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSMGDataMultipleDataConstantUsage(t *testing.T) {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
var acnt *engine.Account
|
||||
attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1010"}
|
||||
eAcntVal := 49997767680.000000
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
smgEv := SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.SETUP_TIME: "2016-01-05 18:30:49",
|
||||
utils.ANSWER_TIME: "2016-01-05 18:31:05",
|
||||
utils.USAGE: "1048576",
|
||||
}
|
||||
var maxUsage float64
|
||||
if err := smgRPC.Call("SMGenericV1.SessionStart", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 1054720
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
aSessions := make([]*ActiveSession, 0)
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1048576 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.USAGE: "1048576",
|
||||
utils.LastUsed: "600",
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.SessionUpdate", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 0
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1049176 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.USAGE: "1048576",
|
||||
utils.LastUsed: "600",
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.SessionUpdate", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 0
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1049776 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.USAGE: "1048576",
|
||||
utils.LastUsed: "600",
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.SessionUpdate", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 0
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1050376 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.USAGE: "1048576",
|
||||
utils.LastUsed: "600",
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.SessionUpdate", smgEv, &maxUsage); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if maxUsage != 1.048576e+06 {
|
||||
t.Error("Bad max usage: ", maxUsage)
|
||||
}
|
||||
eAcntVal = 49996712960.000000 // 0
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 1 || aSessions[0].Usage.Seconds() != 1050976 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
smgEv = SMGenericEvent{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.TOR: utils.DATA,
|
||||
utils.ACCID: "12349",
|
||||
utils.DIRECTION: utils.OUT,
|
||||
utils.ACCOUNT: "1010",
|
||||
utils.SUBJECT: "1010",
|
||||
utils.DESTINATION: "222",
|
||||
utils.CATEGORY: "data",
|
||||
utils.TENANT: "cgrates.org",
|
||||
utils.REQTYPE: utils.META_PREPAID,
|
||||
utils.LastUsed: "0",
|
||||
}
|
||||
var rpl string
|
||||
if err = smgRPC.Call("SMGenericV1.SessionEnd", smgEv, &rpl); err != nil || rpl != utils.OK {
|
||||
t.Error(err)
|
||||
}
|
||||
eAcntVal = 49997757440.000000 // 10240 (from the start)
|
||||
if err := smgRPC.Call("ApierV2.GetAccount", attrs, &acnt); err != nil {
|
||||
t.Error(err)
|
||||
} else if acnt.BalanceMap[utils.DATA].GetTotalValue() != eAcntVal {
|
||||
t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.DATA].GetTotalValue())
|
||||
}
|
||||
if err := smgRPC.Call("SMGenericV1.ActiveSessions", utils.AttrSMGGetActiveSessions{}, &aSessions); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aSessions) != 0 {
|
||||
t.Errorf("wrong active sessions: %f", aSessions[0].Usage.Seconds())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,13 +90,15 @@ func (self *SMGSession) debit(dur time.Duration, lastUsed *time.Duration) (time.
|
||||
// total usage correction
|
||||
self.totalUsage -= self.lastUsage
|
||||
self.totalUsage += *lastUsed
|
||||
//utils.Logger.Debug(fmt.Sprintf("Correction: %f", self.totalUsage.Seconds()))
|
||||
//utils.Logger.Debug(fmt.Sprintf("TotalUsage Correction: %f", self.totalUsage.Seconds()))
|
||||
}
|
||||
}
|
||||
// apply correction from previous run
|
||||
if self.extraDuration < dur {
|
||||
dur -= self.extraDuration
|
||||
} else {
|
||||
self.lastUsage = requestedDuration
|
||||
self.totalUsage += self.lastUsage
|
||||
ccDuration := self.extraDuration // fake ccDuration
|
||||
self.extraDuration -= dur
|
||||
return ccDuration, nil
|
||||
@@ -111,6 +113,7 @@ func (self *SMGSession) debit(dur time.Duration, lastUsed *time.Duration) (time.
|
||||
self.cd.DurationIndex += dur
|
||||
cc := &engine.CallCost{}
|
||||
if err := self.rater.Call("Responder.MaxDebit", self.cd, cc); err != nil {
|
||||
self.lastUsage = 0
|
||||
self.lastDebit = 0
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -275,6 +275,7 @@ type TPActions struct {
|
||||
type TPAction struct {
|
||||
Identifier string // Identifier mapped in the code
|
||||
BalanceId string // Balance identification string (account scope)
|
||||
BalanceUuid string // Balance identification string (global scope)
|
||||
BalanceType string // Type of balance the action will operate on
|
||||
Directions string // Balance direction
|
||||
Units string // Number of units to add/deduct
|
||||
|
||||
@@ -37,6 +37,10 @@ var ValueFormulas = map[string]valueFormula{
|
||||
INCREMENTAL: incrementalFormula,
|
||||
}
|
||||
|
||||
func (vf *ValueFormula) String() string {
|
||||
return ToJSON(vf)
|
||||
}
|
||||
|
||||
func incrementalFormula(params map[string]interface{}) float64 {
|
||||
// check parameters
|
||||
unitsInterface, unitsFound := params["Units"]
|
||||
|
||||
Reference in New Issue
Block a user