From 78764e997959ec2280b5bcc886a00efdcd6045a3 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 10 Jun 2015 14:40:20 +0300 Subject: [PATCH] refund tests --- apier/v1/callsetup.go | 7 +-- apier/v1/costs.go | 2 +- apier/v1/derivedcharging.go | 2 +- engine/cdrs.go | 4 +- engine/handler_derivedcharging.go | 2 +- engine/responder.go | 68 ++++++++++++++--------------- engine/responder_test.go | 8 ++-- sessionmanager/fssessionmanager.go | 16 +++---- sessionmanager/kamailiosm.go | 2 +- sessionmanager/session.go | 14 ++++-- sessionmanager/session_test.go | 69 ++++++++++++++++++++++++++++++ 11 files changed, 135 insertions(+), 59 deletions(-) diff --git a/apier/v1/callsetup.go b/apier/v1/callsetup.go index 0e8f96202..40c88e833 100644 --- a/apier/v1/callsetup.go +++ b/apier/v1/callsetup.go @@ -20,10 +20,11 @@ package v1 import ( "fmt" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" "strconv" "time" + + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" ) // Returns MaxSessionTime in seconds, -1 for no limit @@ -60,7 +61,7 @@ func (self *ApierV1) GetMaxSessionTime(auth engine.MaxUsageReq, maxSessionTime * return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } var maxDur float64 - if err := self.Responder.GetDerivedMaxSessionTime(*storedCdr, &maxDur); err != nil { + if err := self.Responder.GetDerivedMaxSessionTime(storedCdr, &maxDur); err != nil { return err } if maxDur == -1.0 { diff --git a/apier/v1/costs.go b/apier/v1/costs.go index 1f61a0282..8cf756d59 100644 --- a/apier/v1/costs.go +++ b/apier/v1/costs.go @@ -36,7 +36,7 @@ type AttrGetDataCost struct { func (apier *ApierV1) GetDataCost(attrs AttrGetDataCost, reply *engine.DataCost) error { usageAsDuration := time.Duration(attrs.Usage) * time.Second // Convert to seconds to match the loaded rates - cd := engine.CallDescriptor{ + cd := &engine.CallDescriptor{ Direction: attrs.Direction, Category: attrs.Category, Tenant: attrs.Tenant, diff --git a/apier/v1/derivedcharging.go b/apier/v1/derivedcharging.go index 7486a2264..438ee4cbe 100644 --- a/apier/v1/derivedcharging.go +++ b/apier/v1/derivedcharging.go @@ -30,7 +30,7 @@ func (self *ApierV1) GetDerivedChargers(attrs utils.AttrDerivedChargers, reply * if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Direction", "Account", "Subject"}); len(missing) != 0 { return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } - if hDc, err := engine.HandleGetDerivedChargers(self.AccountDb, attrs); err != nil { + if hDc, err := engine.HandleGetDerivedChargers(self.AccountDb, &attrs); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else if hDc != nil { *reply = hDc diff --git a/engine/cdrs.go b/engine/cdrs.go index 648c1405c..e8c3018f6 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -232,7 +232,7 @@ func (self *CdrServer) getCostFromRater(storedCdr *StoredCdr) (*CallCost, error) //} cc := new(CallCost) var err error - cd := CallDescriptor{ + cd := &CallDescriptor{ TOR: storedCdr.TOR, Direction: storedCdr.Direction, Tenant: storedCdr.Tenant, @@ -265,7 +265,7 @@ func (self *CdrServer) deriveCdrs(storedCdr *StoredCdr) ([]*StoredCdr, error) { if storedCdr.Rated { // Do not derive already rated CDRs since they should be already derived return cdrRuns, nil } - attrsDC := utils.AttrDerivedChargers{Tenant: storedCdr.Tenant, Category: storedCdr.Category, Direction: storedCdr.Direction, + attrsDC := &utils.AttrDerivedChargers{Tenant: storedCdr.Tenant, Category: storedCdr.Category, Direction: storedCdr.Direction, Account: storedCdr.Account, Subject: storedCdr.Subject} var dcs utils.DerivedChargers if err := self.rater.GetDerivedChargers(attrsDC, &dcs); err != nil { diff --git a/engine/handler_derivedcharging.go b/engine/handler_derivedcharging.go index 865b3ae81..a0fc1bcaa 100644 --- a/engine/handler_derivedcharging.go +++ b/engine/handler_derivedcharging.go @@ -23,7 +23,7 @@ import ( ) // Handles retrieving of DerivedChargers profile based on longest match from AccountingDb -func HandleGetDerivedChargers(acntStorage AccountingStorage, attrs utils.AttrDerivedChargers) (utils.DerivedChargers, error) { +func HandleGetDerivedChargers(acntStorage AccountingStorage, attrs *utils.AttrDerivedChargers) (utils.DerivedChargers, error) { var dcs utils.DerivedChargers strictKey := utils.DerivedChargersKey(attrs.Direction, attrs.Tenant, attrs.Category, attrs.Account, attrs.Subject) anySubjKey := utils.DerivedChargersKey(attrs.Direction, attrs.Tenant, attrs.Category, attrs.Account, utils.ANY) diff --git a/engine/responder.go b/engine/responder.go index d151b5f7c..ef3cace25 100644 --- a/engine/responder.go +++ b/engine/responder.go @@ -50,9 +50,9 @@ type Responder struct { /* RPC method thet provides the external RPC interface for getting the rating information. */ -func (rs *Responder) GetCost(arg CallDescriptor, reply *CallCost) (err error) { +func (rs *Responder) GetCost(arg *CallDescriptor, reply *CallCost) (err error) { if rs.Bal != nil { - r, e := rs.getCallCost(&arg, "Responder.GetCost") + r, e := rs.getCallCost(arg, "Responder.GetCost") *reply, err = *r, e } else { r, e := AccLock.Guard(func() (interface{}, error) { @@ -67,9 +67,9 @@ func (rs *Responder) GetCost(arg CallDescriptor, reply *CallCost) (err error) { return } -func (rs *Responder) Debit(arg CallDescriptor, reply *CallCost) (err error) { +func (rs *Responder) Debit(arg *CallDescriptor, reply *CallCost) (err error) { if rs.Bal != nil { - r, e := rs.getCallCost(&arg, "Responder.Debit") + r, e := rs.getCallCost(arg, "Responder.Debit") *reply, err = *r, e } else { r, e := arg.Debit() @@ -82,9 +82,9 @@ func (rs *Responder) Debit(arg CallDescriptor, reply *CallCost) (err error) { return } -func (rs *Responder) MaxDebit(arg CallDescriptor, reply *CallCost) (err error) { +func (rs *Responder) MaxDebit(arg *CallDescriptor, reply *CallCost) (err error) { if rs.Bal != nil { - r, e := rs.getCallCost(&arg, "Responder.MaxDebit") + r, e := rs.getCallCost(arg, "Responder.MaxDebit") *reply, err = *r, e } else { r, e := arg.MaxDebit() @@ -97,9 +97,9 @@ func (rs *Responder) MaxDebit(arg CallDescriptor, reply *CallCost) (err error) { return } -func (rs *Responder) RefundIncrements(arg CallDescriptor, reply *float64) (err error) { +func (rs *Responder) RefundIncrements(arg *CallDescriptor, reply *float64) (err error) { if rs.Bal != nil { - *reply, err = rs.callMethod(&arg, "Responder.RefundIncrements") + *reply, err = rs.callMethod(arg, "Responder.RefundIncrements") } else { r, e := AccLock.Guard(func() (interface{}, error) { return arg.RefundIncrements() @@ -109,9 +109,9 @@ func (rs *Responder) RefundIncrements(arg CallDescriptor, reply *float64) (err e return } -func (rs *Responder) GetMaxSessionTime(arg CallDescriptor, reply *float64) (err error) { +func (rs *Responder) GetMaxSessionTime(arg *CallDescriptor, reply *float64) (err error) { if rs.Bal != nil { - *reply, err = rs.callMethod(&arg, "Responder.GetMaxSessionTime") + *reply, err = rs.callMethod(arg, "Responder.GetMaxSessionTime") } else { r, e := arg.GetMaxSessionDuration() *reply, err = float64(r), e @@ -120,12 +120,12 @@ func (rs *Responder) GetMaxSessionTime(arg CallDescriptor, reply *float64) (err } // Returns MaxSessionTime for an event received in SessionManager, considering DerivedCharging for it -func (rs *Responder) GetDerivedMaxSessionTime(ev StoredCdr, reply *float64) error { +func (rs *Responder) GetDerivedMaxSessionTime(ev *StoredCdr, reply *float64) error { if rs.Bal != nil { return errors.New("unsupported method on the balancer") } maxCallDuration := -1.0 - attrsDC := utils.AttrDerivedChargers{Tenant: ev.GetTenant(utils.META_DEFAULT), Category: ev.GetCategory(utils.META_DEFAULT), Direction: ev.GetDirection(utils.META_DEFAULT), + attrsDC := &utils.AttrDerivedChargers{Tenant: ev.GetTenant(utils.META_DEFAULT), Category: ev.GetCategory(utils.META_DEFAULT), Direction: ev.GetDirection(utils.META_DEFAULT), Account: ev.GetAccount(utils.META_DEFAULT), Subject: ev.GetSubject(utils.META_DEFAULT)} var dcs utils.DerivedChargers if err := rs.GetDerivedChargers(attrsDC, &dcs); err != nil { @@ -151,7 +151,7 @@ func (rs *Responder) GetDerivedMaxSessionTime(ev StoredCdr, reply *float64) erro if err != nil { return err } - cd := CallDescriptor{ + cd := &CallDescriptor{ Direction: ev.GetDirection(dc.DirectionField), Tenant: ev.GetTenant(dc.TenantField), Category: ev.GetCategory(dc.CategoryField), @@ -179,11 +179,11 @@ func (rs *Responder) GetDerivedMaxSessionTime(ev StoredCdr, reply *float64) erro } // Used by SM to get all the prepaid CallDescriptors attached to a session -func (rs *Responder) GetSessionRuns(ev StoredCdr, sRuns *[]*SessionRun) error { +func (rs *Responder) GetSessionRuns(ev *StoredCdr, sRuns *[]*SessionRun) error { if rs.Bal != nil { return errors.New("Unsupported method on the balancer") } - attrsDC := utils.AttrDerivedChargers{Tenant: ev.GetTenant(utils.META_DEFAULT), Category: ev.GetCategory(utils.META_DEFAULT), Direction: ev.GetDirection(utils.META_DEFAULT), + attrsDC := &utils.AttrDerivedChargers{Tenant: ev.GetTenant(utils.META_DEFAULT), Category: ev.GetCategory(utils.META_DEFAULT), Direction: ev.GetDirection(utils.META_DEFAULT), Account: ev.GetAccount(utils.META_DEFAULT), Subject: ev.GetSubject(utils.META_DEFAULT)} var dcs utils.DerivedChargers if err := rs.GetDerivedChargers(attrsDC, &dcs); err != nil { @@ -213,7 +213,7 @@ func (rs *Responder) GetSessionRuns(ev StoredCdr, sRuns *[]*SessionRun) error { return nil } -func (rs *Responder) GetDerivedChargers(attrs utils.AttrDerivedChargers, dcs *utils.DerivedChargers) error { +func (rs *Responder) GetDerivedChargers(attrs *utils.AttrDerivedChargers, dcs *utils.DerivedChargers) error { if rs.Bal != nil { return errors.New("BALANCER_UNSUPPORTED_METHOD") } @@ -256,9 +256,9 @@ func (rs *Responder) GetLCR(cd *CallDescriptor, reply *LCRCost) error { return nil } -func (rs *Responder) FlushCache(arg CallDescriptor, reply *float64) (err error) { +func (rs *Responder) FlushCache(arg *CallDescriptor, reply *float64) (err error) { if rs.Bal != nil { - *reply, err = rs.callMethod(&arg, "Responder.FlushCache") + *reply, err = rs.callMethod(arg, "Responder.FlushCache") } else { r, e := AccLock.Guard(func() (interface{}, error) { return 0, arg.FlushCache() @@ -405,14 +405,14 @@ func (rw *ResponderWorker) Close() error { } type Connector interface { - GetCost(CallDescriptor, *CallCost) error - Debit(CallDescriptor, *CallCost) error - MaxDebit(CallDescriptor, *CallCost) error - RefundIncrements(CallDescriptor, *float64) error - GetMaxSessionTime(CallDescriptor, *float64) error - GetDerivedChargers(utils.AttrDerivedChargers, *utils.DerivedChargers) error - GetDerivedMaxSessionTime(StoredCdr, *float64) error - GetSessionRuns(StoredCdr, *[]*SessionRun) error + GetCost(*CallDescriptor, *CallCost) error + Debit(*CallDescriptor, *CallCost) error + MaxDebit(*CallDescriptor, *CallCost) error + RefundIncrements(*CallDescriptor, *float64) error + GetMaxSessionTime(*CallDescriptor, *float64) error + GetDerivedChargers(*utils.AttrDerivedChargers, *utils.DerivedChargers) error + GetDerivedMaxSessionTime(*StoredCdr, *float64) error + GetSessionRuns(*StoredCdr, *[]*SessionRun) error ProcessCdr(*StoredCdr, *string) error LogCallCost(*CallCostLog, *string) error GetLCR(*CallDescriptor, *LCRCost) error @@ -422,35 +422,35 @@ type RPCClientConnector struct { Client *rpcclient.RpcClient } -func (rcc *RPCClientConnector) GetCost(cd CallDescriptor, cc *CallCost) error { +func (rcc *RPCClientConnector) GetCost(cd *CallDescriptor, cc *CallCost) error { return rcc.Client.Call("Responder.GetCost", cd, cc) } -func (rcc *RPCClientConnector) Debit(cd CallDescriptor, cc *CallCost) error { +func (rcc *RPCClientConnector) Debit(cd *CallDescriptor, cc *CallCost) error { return rcc.Client.Call("Responder.Debit", cd, cc) } -func (rcc *RPCClientConnector) MaxDebit(cd CallDescriptor, cc *CallCost) error { +func (rcc *RPCClientConnector) MaxDebit(cd *CallDescriptor, cc *CallCost) error { return rcc.Client.Call("Responder.MaxDebit", cd, cc) } -func (rcc *RPCClientConnector) RefundIncrements(cd CallDescriptor, resp *float64) error { +func (rcc *RPCClientConnector) RefundIncrements(cd *CallDescriptor, resp *float64) error { return rcc.Client.Call("Responder.RefundIncrements", cd, resp) } -func (rcc *RPCClientConnector) GetMaxSessionTime(cd CallDescriptor, resp *float64) error { +func (rcc *RPCClientConnector) GetMaxSessionTime(cd *CallDescriptor, resp *float64) error { return rcc.Client.Call("Responder.GetMaxSessionTime", cd, resp) } -func (rcc *RPCClientConnector) GetDerivedMaxSessionTime(ev StoredCdr, reply *float64) error { +func (rcc *RPCClientConnector) GetDerivedMaxSessionTime(ev *StoredCdr, reply *float64) error { return rcc.Client.Call("Responder.GetDerivedMaxSessionTime", ev, reply) } -func (rcc *RPCClientConnector) GetSessionRuns(ev StoredCdr, sRuns *[]*SessionRun) error { +func (rcc *RPCClientConnector) GetSessionRuns(ev *StoredCdr, sRuns *[]*SessionRun) error { return rcc.Client.Call("Responder.GetSessionRuns", ev, sRuns) } -func (rcc *RPCClientConnector) GetDerivedChargers(attrs utils.AttrDerivedChargers, dcs *utils.DerivedChargers) error { +func (rcc *RPCClientConnector) GetDerivedChargers(attrs *utils.AttrDerivedChargers, dcs *utils.DerivedChargers) error { return rcc.Client.Call("ApierV1.GetDerivedChargers", attrs, dcs) } diff --git a/engine/responder_test.go b/engine/responder_test.go index 7cd82ca55..eed6f8111 100644 --- a/engine/responder_test.go +++ b/engine/responder_test.go @@ -40,7 +40,7 @@ func TestResponderGetDerivedChargers(t *testing.T) { cfgedDC := utils.DerivedChargers{&utils.DerivedCharger{RunId: "responder1", ReqTypeField: "test", DirectionField: "test", TenantField: "test", CategoryField: "test", AccountField: "test", SubjectField: "test", DestinationField: "test", SetupTimeField: "test", AnswerTimeField: "test", UsageField: "test"}} rsponder = &Responder{} - attrs := utils.AttrDerivedChargers{Tenant: "cgrates.org", Category: "call", Direction: "*out", Account: "responder_test", Subject: "responder_test"} + attrs := &utils.AttrDerivedChargers{Tenant: "cgrates.org", Category: "call", Direction: "*out", Account: "responder_test", Subject: "responder_test"} if err := accountingStorage.SetDerivedChargers(utils.DerivedChargersKey(utils.OUT, utils.ANY, utils.ANY, utils.ANY, utils.ANY), cfgedDC); err != nil { t.Error(err) } @@ -57,7 +57,7 @@ func TestResponderGetDerivedChargers(t *testing.T) { func TestGetDerivedMaxSessionTime(t *testing.T) { testTenant := "vdf" - cdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + cdr := &StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_RATED, Direction: "*out", Tenant: testTenant, Category: "call", Account: "dan", Subject: "dan", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, @@ -109,7 +109,7 @@ func TestGetDerivedMaxSessionTime(t *testing.T) { t.Error("BalanceValue: ", danStoredAcnt.BalanceMap[utils.VOICE+OUTBOUND][0].Value) } var dcs utils.DerivedChargers - attrs := utils.AttrDerivedChargers{Tenant: testTenant, Category: "call", Direction: "*out", Account: "dan", Subject: "dan"} + attrs := &utils.AttrDerivedChargers{Tenant: testTenant, Category: "call", Direction: "*out", Account: "dan", Subject: "dan"} if err := rsponder.GetDerivedChargers(attrs, &dcs); err != nil { t.Error("Unexpected error", err.Error()) } else if !reflect.DeepEqual(dcs, charger1) { @@ -125,7 +125,7 @@ func TestGetDerivedMaxSessionTime(t *testing.T) { func TestGetSessionRuns(t *testing.T) { testTenant := "vdf" - cdr := StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", + cdr := &StoredCdr{CgrId: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), OrderId: 123, TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.META_PREPAID, Direction: "*out", Tenant: testTenant, Category: "call", Account: "dan2", Subject: "dan2", Destination: "1002", SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), Pdd: 3 * time.Second, AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), Supplier: "suppl1", MediationRunId: utils.DEFAULT_RUNID, Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, diff --git a/sessionmanager/fssessionmanager.go b/sessionmanager/fssessionmanager.go index 5dcf21d68..c2b65a5f4 100644 --- a/sessionmanager/fssessionmanager.go +++ b/sessionmanager/fssessionmanager.go @@ -37,15 +37,15 @@ type FSSessionManager struct { conns map[string]*fsock.FSock // Keep the list here for connection management purposes sessions []*Session rater engine.Connector - cdrs engine.Connector + cdrsrv engine.Connector } func NewFSSessionManager(smFsConfig *config.SmFsConfig, rater, cdrs engine.Connector) *FSSessionManager { return &FSSessionManager{ - cfg: smFsConfig, - conns: make(map[string]*fsock.FSock), - rater: rater, - cdrs: cdrs, + cfg: smFsConfig, + conns: make(map[string]*fsock.FSock), + rater: rater, + cdrsrv: cdrs, } } @@ -204,7 +204,7 @@ func (sm *FSSessionManager) onChannelPark(ev engine.Event, connId string) { return } var maxCallDuration float64 // This will be the maximum duration this channel will be allowed to last - if err := sm.rater.GetDerivedMaxSessionTime(*ev.AsStoredCdr(), &maxCallDuration); err != nil { + if err := sm.rater.GetDerivedMaxSessionTime(ev.AsStoredCdr(), &maxCallDuration); err != nil { engine.Logger.Err(fmt.Sprintf(" Could not get max session time for %s, error: %s", ev.GetUUID(), err.Error())) } maxCallDur := time.Duration(maxCallDuration) @@ -265,7 +265,7 @@ func (sm *FSSessionManager) onChannelHangupComplete(ev engine.Event) { func (sm *FSSessionManager) ProcessCdr(storedCdr *engine.StoredCdr) error { var reply string - if err := sm.cdrs.ProcessCdr(storedCdr, &reply); err != nil { + if err := sm.cdrsrv.ProcessCdr(storedCdr, &reply); err != nil { engine.Logger.Err(fmt.Sprintf(" Failed processing CDR, cgrid: %s, accid: %s, error: <%s>", storedCdr.CgrId, storedCdr.AccId, err.Error())) } return nil @@ -275,7 +275,7 @@ func (sm *FSSessionManager) DebitInterval() time.Duration { return sm.cfg.DebitInterval } func (sm *FSSessionManager) CdrSrv() engine.Connector { - return sm.cdrs + return sm.cdrsrv } func (sm *FSSessionManager) Rater() engine.Connector { diff --git a/sessionmanager/kamailiosm.go b/sessionmanager/kamailiosm.go index 760017ed8..920eb6835 100644 --- a/sessionmanager/kamailiosm.go +++ b/sessionmanager/kamailiosm.go @@ -63,7 +63,7 @@ func (self *KamailioSessionManager) onCgrAuth(evData []byte, connId string) { } var remainingDuration float64 var errMaxSession error - if errMaxSession = self.rater.GetDerivedMaxSessionTime(*kev.AsStoredCdr(), &remainingDuration); errMaxSession != nil { + if errMaxSession = self.rater.GetDerivedMaxSessionTime(kev.AsStoredCdr(), &remainingDuration); errMaxSession != nil { engine.Logger.Err(fmt.Sprintf(" Could not get max session time, error: %s", errMaxSession.Error())) } var supplStr string diff --git a/sessionmanager/session.go b/sessionmanager/session.go index 0333ad16a..e2454c445 100644 --- a/sessionmanager/session.go +++ b/sessionmanager/session.go @@ -59,7 +59,7 @@ func NewSession(ev engine.Event, connId string, sm SessionManager) *Session { sessionManager: sm, connId: connId, } - if err := sm.Rater().GetSessionRuns(*ev.AsStoredCdr(), &s.sessionRuns); err != nil || len(s.sessionRuns) == 0 { + if err := sm.Rater().GetSessionRuns(ev.AsStoredCdr(), &s.sessionRuns); err != nil || len(s.sessionRuns) == 0 { return nil } for runIdx := range s.sessionRuns { @@ -70,7 +70,7 @@ func NewSession(ev engine.Event, connId string, sm SessionManager) *Session { // the debit loop method (to be stoped by sending somenthing on stopDebit channel) func (s *Session) debitLoop(runIdx int) { - nextCd := *s.sessionRuns[runIdx].CallDescriptor + nextCd := s.sessionRuns[runIdx].CallDescriptor index := 0.0 debitPeriod := s.sessionManager.DebitInterval() for { @@ -154,6 +154,7 @@ func (s *Session) Refund(lastCC *engine.CallCost, hangupTime time.Time) error { ts := lastCC.Timespans[i] tsDuration := ts.GetDuration() if refundDuration <= tsDuration { + lastRefundedIncrementIndex := 0 for j := len(ts.Increments) - 1; j >= 0; j-- { increment := ts.Increments[j] @@ -163,7 +164,12 @@ func (s *Session) Refund(lastCC *engine.CallCost, hangupTime time.Time) error { lastRefundedIncrementIndex = j } } - ts.SplitByIncrement(lastRefundedIncrementIndex) + if lastRefundedIncrementIndex == 0 { + lastCC.Timespans[i] = nil + lastCC.Timespans = lastCC.Timespans[:i] + } else { + ts.SplitByIncrement(lastRefundedIncrementIndex) + } break // do not go to other timespans } else { refundIncrements = append(refundIncrements, ts.Increments...) @@ -187,7 +193,7 @@ func (s *Session) Refund(lastCC *engine.CallCost, hangupTime time.Time) error { Increments: refundIncrements, } var response float64 - err := s.sessionManager.Rater().RefundIncrements(*cd, &response) + err := s.sessionManager.Rater().RefundIncrements(cd, &response) if err != nil { return err } diff --git a/sessionmanager/session_test.go b/sessionmanager/session_test.go index b88e65bc0..7af0fa453 100644 --- a/sessionmanager/session_test.go +++ b/sessionmanager/session_test.go @@ -18,6 +18,14 @@ along with this program. If not, see package sessionmanager +import ( + "testing" + "time" + + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + //"github.com/cgrates/cgrates/config" //"testing" @@ -71,3 +79,64 @@ func TestSessionNilSession(t *testing.T) { } } */ + +type MockConnector struct { + refundCd *engine.CallDescriptor +} + +func (mc *MockConnector) GetCost(*engine.CallDescriptor, *engine.CallCost) error { return nil } +func (mc *MockConnector) Debit(*engine.CallDescriptor, *engine.CallCost) error { return nil } +func (mc *MockConnector) MaxDebit(*engine.CallDescriptor, *engine.CallCost) error { return nil } +func (mc *MockConnector) RefundIncrements(cd *engine.CallDescriptor, reply *float64) error { + mc.refundCd = cd + return nil +} +func (mc *MockConnector) GetMaxSessionTime(*engine.CallDescriptor, *float64) error { return nil } +func (mc *MockConnector) GetDerivedChargers(*utils.AttrDerivedChargers, *utils.DerivedChargers) error { + return nil +} +func (mc *MockConnector) GetDerivedMaxSessionTime(*engine.StoredCdr, *float64) error { return nil } +func (mc *MockConnector) GetSessionRuns(*engine.StoredCdr, *[]*engine.SessionRun) error { return nil } +func (mc *MockConnector) ProcessCdr(*engine.StoredCdr, *string) error { return nil } +func (mc *MockConnector) LogCallCost(*engine.CallCostLog, *string) error { return nil } +func (mc *MockConnector) GetLCR(*engine.CallDescriptor, *engine.LCRCost) error { return nil } + +func TestSessionRefund(t *testing.T) { + mc := &MockConnector{} + s := &Session{sessionManager: &FSSessionManager{rater: mc}} + ts := &engine.TimeSpan{ + TimeStart: time.Date(2015, 6, 10, 14, 07, 0, 0, time.UTC), + TimeEnd: time.Date(2015, 6, 10, 14, 07, 30, 0, time.UTC), + } + // add increments + for i := 0; i < 30; i++ { + ts.AddIncrement(&engine.Increment{Duration: time.Second, Cost: 1.0}) + } + + cc := &engine.CallCost{Timespans: engine.TimeSpans{ts}} + hangupTime := time.Date(2015, 6, 10, 14, 07, 20, 0, time.UTC) + s.Refund(cc, hangupTime) + if len(mc.refundCd.Increments) != 10 || len(cc.Timespans) != 1 || cc.Timespans[0].TimeEnd != hangupTime { + t.Errorf("Error refunding: %+v, %+v", mc.refundCd.Increments, cc.Timespans[0]) + } +} + +func TestSessionRefundAll(t *testing.T) { + mc := &MockConnector{} + s := &Session{sessionManager: &FSSessionManager{rater: mc}} + ts := &engine.TimeSpan{ + TimeStart: time.Date(2015, 6, 10, 14, 07, 0, 0, time.UTC), + TimeEnd: time.Date(2015, 6, 10, 14, 07, 30, 0, time.UTC), + } + // add increments + for i := 0; i < 30; i++ { + ts.AddIncrement(&engine.Increment{Duration: time.Second, Cost: 1.0}) + } + + cc := &engine.CallCost{Timespans: engine.TimeSpans{ts}} + hangupTime := time.Date(2015, 6, 10, 14, 07, 0, 0, time.UTC) + s.Refund(cc, hangupTime) + if len(mc.refundCd.Increments) != 30 || len(cc.Timespans) != 0 { + t.Errorf("Error refunding: %+v, %+v", len(mc.refundCd.Increments), cc.Timespans[0]) + } +}