mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Fixup CdrServer receiving nanoseconds as usage, more tests
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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",
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"],
|
||||
|
||||
Reference in New Issue
Block a user