Fixup CdrServer receiving nanoseconds as usage, more tests

This commit is contained in:
DanB
2014-05-19 17:50:31 +02:00
parent d5f6df9473
commit 1ad4068d73
8 changed files with 105 additions and 19 deletions

View File

@@ -64,14 +64,8 @@ func (self *ApierV1) GetRatingPlan(rplnId string, reply *engine.RatingPlan) erro
return nil
}
type AttrGetAccount struct {
Tenant string
Account string
Direction string
}
// Get balance
func (self *ApierV1) GetAccount(attr *AttrGetAccount, reply *engine.Account) error {
func (self *ApierV1) GetAccount(attr *utils.AttrGetAccount, reply *engine.Account) error {
tag := fmt.Sprintf("%s:%s:%s", attr.Direction, attr.Tenant, attr.Account)
userBalance, err := self.AccountDb.GetAccount(tag)
if err != nil {

View File

@@ -19,15 +19,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package console
import (
"github.com/cgrates/cgrates/apier"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
func init() {
c := &CmdGetAccount{
name: "account",
rpcMethod: "ApierV1.GetAccount",
rpcParams: &apier.AttrGetAccount{Direction: "*out"},
rpcParams: &utils.AttrGetAccount{Direction: "*out"},
}
commands[c.Name()] = c
c.CommandExecuter = &CommandExecuter{c}
@@ -37,7 +37,7 @@ func init() {
type CmdGetAccount struct {
name string
rpcMethod string
rpcParams *apier.AttrGetAccount
rpcParams *utils.AttrGetAccount
*CommandExecuter
}
@@ -51,7 +51,7 @@ func (self *CmdGetAccount) RpcMethod() string {
func (self *CmdGetAccount) RpcParams() interface{} {
if self.rpcParams == nil {
self.rpcParams = &apier.AttrGetAccount{Direction: "*out"}
self.rpcParams = &utils.AttrGetAccount{Direction: "*out"}
}
return self.rpcParams
}

View File

@@ -6,6 +6,9 @@
[rater]
enabled = true # Enable RaterCDRSExportPath service: <true|false>.
[scheduler]
enabled = true # Starts Scheduler service: <true|false>.
[cdrs]
enabled = true # Start the CDR Server service: <true|false>.
mediator = internal # Address where to reach the Mediator. Empty for disabling mediation. <""|internal>

View File

@@ -35,10 +35,14 @@ func TestSetStorageDtChrg1(t *testing.T) {
}
func TestLoadCsvTpDtChrg1(t *testing.T) {
timings := `ALWAYS,*any,*any,*any,*any,00:00:00`
rates := `RT_DATA_2c,0,0.002,10,10,0`
destinationRates := `DR_DATA_1,*any,RT_DATA_2c,*up,4`
ratingPlans := `RP_DATA1,DR_DATA_1,ALWAYS,10`
timings := `TM1,*any,*any,*any,*any,00:00:00
TM2,*any,*any,*any,*any,01:00:00`
rates := `RT_DATA_2c,0,0.002,10,10,0
RT_DATA_1c,0,0.001,10,10,0`
destinationRates := `DR_DATA_1,*any,RT_DATA_2c,*up,4
DR_DATA_2,*any,RT_DATA_1c,*up,4`
ratingPlans := `RP_DATA1,DR_DATA_1,TM1,10
RP_DATA1,DR_DATA_2,TM2,10`
ratingProfiles := `*out,cgrates.org,data,*any,2012-01-01T00:00:00Z,RP_DATA1,`
csvr := engine.NewStringCSVReader(ratingDb, acntDb, ',', "", timings, rates, destinationRates, ratingPlans, ratingProfiles,
"", "", "", "", "", "", "")
@@ -71,7 +75,51 @@ func TestLoadCsvTpDtChrg1(t *testing.T) {
func TestGetDataCostDtChrg1(t *testing.T) {
usedData := 20
usageDur := time.Duration(usedData) * time.Second
timeStart := time.Date(2014, 3, 4, 6, 0, 0, 0, time.UTC)
timeStart := time.Date(2014, 3, 4, 0, 0, 0, 0, time.Local)
cd := &engine.CallDescriptor{
Direction: "*out",
Category: "data",
Tenant: "cgrates.org",
Subject: "12345",
Account: "12345",
TimeStart: timeStart,
TimeEnd: timeStart.Add(usageDur),
DurationIndex: usageDur,
TOR: utils.DATA,
}
if cc, err := cd.GetCost(); err != nil {
t.Error(err)
} else if cc.Cost != 0.004 {
t.Error("Wrong cost returned: ", cc.Cost)
}
}
func TestGetDataCostSecondIntDtChrg1(t *testing.T) {
usedData := 20
usageDur := time.Duration(usedData) * time.Second
timeStart := time.Date(2014, 3, 4, 1, 0, 0, 0, time.Local)
cd := &engine.CallDescriptor{
Direction: "*out",
Category: "data",
Tenant: "cgrates.org",
Subject: "12345",
Account: "12345",
TimeStart: timeStart,
TimeEnd: timeStart.Add(usageDur),
DurationIndex: usageDur,
TOR: utils.DATA,
}
if cc, err := cd.GetCost(); err != nil {
t.Error(err)
} else if cc.Cost != 0.002 {
t.Error("Wrong cost returned: ", cc.Cost)
}
}
func TestGetBetweenCostDtChrg1(t *testing.T) {
usedData := 20
usageDur := time.Duration(usedData) * time.Second
timeStart := time.Date(2014, 3, 4, 0, 59, 50, 0, time.Local)
cd := &engine.CallDescriptor{
Direction: "*out",
Category: "data",

View File

@@ -51,6 +51,7 @@ README:
var cfg *config.CGRConfig
var cgrRpc *rpc.Client
var cdrStor engine.CdrStorage
var httpClient *http.Client
var testLocal = flag.Bool("local", false, "Perform the tests only on local test environment, not by default.") // This flag will be passed here via "go test -local" args
var dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
@@ -117,6 +118,7 @@ func TestStartEngine(t *testing.T) {
t.Fatal("Cannot start cgr-engine: ", err.Error())
}
time.Sleep(time.Duration(*startDelay) * time.Millisecond) // Give time to rater to fire up
httpClient = new(http.Client)
}
// Connect rpc client
@@ -135,7 +137,6 @@ func TestPostCdrs(t *testing.T) {
if !*testLocal {
return
}
httpClient := new(http.Client)
cdrForm1 := url.Values{utils.TOR: []string{utils.VOICE}, utils.ACCID: []string{"dsafdsaf"}, utils.CDRHOST: []string{"192.168.1.1"}, utils.REQTYPE: []string{"rated"}, utils.DIRECTION: []string{"*out"},
utils.TENANT: []string{"cgrates.org"}, utils.CATEGORY: []string{"call"}, utils.ACCOUNT: []string{"1001"}, utils.SUBJECT: []string{"1001"},
utils.DESTINATION: []string{"+4986517174963"},
@@ -241,6 +242,40 @@ func TestRateCdrs(t *testing.T) {
}
}
func TestMediatePseudoprepaid(t *testing.T) {
if !*testLocal {
return
}
var reply *engine.Account
attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1003", Direction: "*out"}
if err := cgrRpc.Call("ApierV1.GetAccount", attrs, &reply); err != nil {
t.Error("Got error on ApierV1.GetAccount: ", err.Error())
} else if reply.BalanceMap[engine.CREDIT+attrs.Direction].GetTotalValue() != 11 {
t.Errorf("Calling ApierV1.GetBalance expected: 10.0, received: %f", reply.BalanceMap[engine.CREDIT+attrs.Direction].GetTotalValue())
}
voiceCdr := &utils.StoredCdr{TOR: utils.VOICE, AccId: "dsafdsaf", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.PSEUDOPREPAID, Direction: utils.OUT,
Tenant: "cgrates.org", Category: "call", Account: "1003", Subject: "1003", Destination: "+4986517174963",
SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
Usage: time.Duration(5) * time.Second}
dataCdr := &utils.StoredCdr{TOR: utils.DATA, AccId: "6163508432", CdrHost: "192.168.1.1", CdrSource: "test", ReqType: utils.PSEUDOPREPAID, Direction: utils.OUT,
Tenant: "cgrates.org", Category: "data", Account: "1003", Subject: "1003",
SetupTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC),
Usage: time.Duration(10) * time.Second}
for _, cdrForm := range []url.Values{voiceCdr.AsHttpForm(), dataCdr.AsHttpForm()} {
cdrForm.Set(utils.CDRSOURCE, engine.TEST_SQL)
if _, err := httpClient.PostForm(fmt.Sprintf("http://%s/cgr", cfg.HTTPListen), cdrForm); err != nil {
t.Error(err.Error())
}
}
time.Sleep(time.Duration(*startDelay) * time.Millisecond) // Give time for debits to happen
expectBalance := 5.998
if err := cgrRpc.Call("ApierV1.GetAccount", attrs, &reply); err != nil {
t.Error("Got error on ApierV1.GetAccount: ", err.Error())
} else if reply.BalanceMap[engine.CREDIT+attrs.Direction].GetTotalValue() != expectBalance { // 5 from voice, 0.002 from DATA
t.Errorf("Calling ApierV1.GetBalance expected: %f, received: %f", expectBalance, reply.BalanceMap[engine.CREDIT+attrs.Direction].GetTotalValue())
}
}
// Simply kill the engine after we are done with tests within this file
func TestStopEngine(t *testing.T) {
if !*testLocal {

View File

@@ -277,6 +277,12 @@ func (self *TPAccountActions) KeyId() string {
return fmt.Sprintf("%s:%s:%s", self.Direction, self.Tenant, self.Account)
}
type AttrGetAccount struct {
Tenant string
Account string
Direction string
}
// Data used to do remote cache reloads via api
type ApiReloadCache struct {
DestinationIds []string

View File

@@ -69,7 +69,7 @@ func (cgrCdr CgrCdr) AsStoredCdr() *StoredCdr {
storCdr.Destination = cgrCdr[DESTINATION]
storCdr.SetupTime, _ = ParseTimeDetectLayout(cgrCdr[SETUP_TIME]) // Not interested to process errors, should do them if necessary in a previous step
storCdr.AnswerTime, _ = ParseTimeDetectLayout(cgrCdr[ANSWER_TIME])
storCdr.Usage, _ = ParseDurationWithSecs(cgrCdr[USAGE])
storCdr.Usage, _ = ParseDurationWithNanosecs(cgrCdr[USAGE])
storCdr.ExtraFields = cgrCdr.getExtraFields()
storCdr.Cost = -1
return storCdr

View File

@@ -34,7 +34,7 @@ func TestCgrCdrInterfaces(t *testing.T) {
func TestCgrCdrAsStoredCdr(t *testing.T) {
cgrCdr := CgrCdr{TOR: VOICE, ACCID: "dsafdsaf", CDRHOST: "192.168.1.1", CDRSOURCE: "internal_test", REQTYPE: "rated", DIRECTION: "*out", TENANT: "cgrates.org", CATEGORY: "call",
ACCOUNT: "1001", SUBJECT: "1001", DESTINATION: "1002", SETUP_TIME: "2013-11-07T08:42:20Z", ANSWER_TIME: "2013-11-07T08:42:26Z", USAGE: "10",
ACCOUNT: "1001", SUBJECT: "1001", DESTINATION: "1002", SETUP_TIME: "2013-11-07T08:42:20Z", ANSWER_TIME: "2013-11-07T08:42:26Z", USAGE: "10000000000",
"field_extr1": "val_extr1", "fieldextr2": "valextr2"}
setupTime, _ := ParseTimeDetectLayout(cgrCdr["setup_time"])
expctRtCdr := &StoredCdr{CgrId: Sha1(cgrCdr["accid"], setupTime.String()), TOR: VOICE, AccId: cgrCdr["accid"], CdrHost: cgrCdr["cdrhost"], CdrSource: cgrCdr["cdrsource"], ReqType: cgrCdr["reqtype"],