mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Unified storage SetCdr and SetRatedCdr into SetCDR, engine/storage_cdrs_it_test should automate testing for the supported StoredDb drivers
This commit is contained in:
@@ -79,7 +79,7 @@ func TestV2CdrsMongoInjectUnratedCdr(t *testing.T) {
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
if err := mysqlDb.SetCdr(strCdr1); err != nil {
|
||||
if err := mysqlDb.SetCDR(strCdr1, false); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ var cdrsCfgPath string
|
||||
var cdrsCfg *config.CGRConfig
|
||||
var cdrsRpc *rpc.Client
|
||||
|
||||
func TestV2CdrsMysqlInitConfig(t *testing.T) {
|
||||
func TestV2CdrsMysqlAInitConfig(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func TestV2CdrsMysqlInitConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestV2CdrsMysqlInitDataDb(t *testing.T) {
|
||||
func TestV2CdrsMysqAlInitDataDb(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func TestV2CdrsMysqlInitDataDb(t *testing.T) {
|
||||
}
|
||||
|
||||
// InitDb so we can rely on count
|
||||
func TestV2CdrsMysqlInitCdrDb(t *testing.T) {
|
||||
func TestV2CdrsMysqlAInitCdrDb(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
@@ -69,7 +69,7 @@ func TestV2CdrsMysqlInitCdrDb(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestV2CdrsMysqlInjectUnratedCdr(t *testing.T) {
|
||||
func TestV2CdrsMysqlAInjectUnratedCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
@@ -79,13 +79,13 @@ func TestV2CdrsMysqlInjectUnratedCdr(t *testing.T) {
|
||||
t.Error("Error on opening database connection: ", err)
|
||||
return
|
||||
}
|
||||
strCdr1 := &engine.CDR{CGRID: utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()),
|
||||
strCdr1 := &engine.CDR{CGRID: utils.Sha1("bbb1", time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC).String()), RunID: utils.MetaRaw,
|
||||
TOR: utils.VOICE, OriginID: "bbb1", OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC), AnswerTime: time.Date(2015, 11, 21, 10, 47, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
if err := mysqlDb.SetCdr(strCdr1); err != nil {
|
||||
Cost: 1.201}
|
||||
if err := mysqlDb.SetCDR(strCdr1, false); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ func TestV2CdrsPsqlInjectUnratedCdr(t *testing.T) {
|
||||
SetupTime: time.Date(2015, 11, 21, 10, 47, 24, 0, time.UTC), AnswerTime: time.Date(2015, 11, 21, 10, 47, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
if err := psqlDb.SetCdr(strCdr1); err != nil {
|
||||
if err := psqlDb.SetCDR(strCdr1, false); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
13
data/conf/samples/storage/mysql/cgrates.json
Normal file
13
data/conf/samples/storage/mysql/cgrates.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
// CGRateS Configuration file used for testing mysql implementation
|
||||
|
||||
"stor_db": { // database used to store offline tariff plans and CDRs
|
||||
"db_type": "mysql", // stor database type to use: <mysql|postgres>
|
||||
"db_host": "127.0.0.1", // the host to connect to
|
||||
"db_port": 3306, // the port to reach the stordb
|
||||
"db_name": "cgrates", // stor database name
|
||||
"db_user": "cgrates", // username to use when connecting to stordb
|
||||
"db_passwd": "CGRateS.org", // password to use when connecting to stordb
|
||||
},
|
||||
|
||||
}
|
||||
13
data/conf/samples/storage/postgres/cgrates.json
Normal file
13
data/conf/samples/storage/postgres/cgrates.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
// CGRateS Configuration file used for testing mysql implementation
|
||||
|
||||
"stor_db": { // database used to store offline tariff plans and CDRs
|
||||
"db_type": "postgres", // stor database type to use: <mysql|postgres>
|
||||
"db_host": "127.0.0.1", // the host to connect to
|
||||
"db_port": 5432, // the port to reach the stordb
|
||||
"db_name": "cgrates", // stor database name
|
||||
"db_user": "cgrates", // username to use when connecting to stordb
|
||||
"db_passwd": "CGRateS.org", // password to use when connecting to stordb
|
||||
},
|
||||
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
--
|
||||
-- Table structure for table `cdrs`
|
||||
--
|
||||
@@ -28,13 +27,11 @@ CREATE TABLE cdrs (
|
||||
extra_fields text NOT NULL,
|
||||
cost_source varchar(64) NOT NULL,
|
||||
cost DECIMAL(20,4) NOT NULL,
|
||||
timespans text,
|
||||
cost_details text,
|
||||
extra_info text,
|
||||
created_at TIMESTAMP,
|
||||
updated_at TIMESTAMP,
|
||||
deleted_at TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY cgrid (cgrid),
|
||||
KEY answer_time_idx (answer_time),
|
||||
KEY deleted_at_idx (deleted_at)
|
||||
UNIQUE KEY cdrrun (cgrid, run_id)
|
||||
);
|
||||
|
||||
@@ -24,15 +24,15 @@ CREATE TABLE cdrs (
|
||||
usage NUMERIC(30,9) NOT NULL,
|
||||
supplier VARCHAR(128) NOT NULL,
|
||||
disconnect_cause VARCHAR(64) NOT NULL,
|
||||
extra_fields jsonb NOT NULL,
|
||||
cost NUMERIC(20,4) DEFAULT NULL,
|
||||
timespans jsonb,
|
||||
extra_fields jsonb,
|
||||
cost_source VARCHAR(64) NOT NULL,
|
||||
cost NUMERIC(20,4) DEFAULT NULL,
|
||||
cost_details jsonb,
|
||||
extra_info text,
|
||||
created_at TIMESTAMP,
|
||||
updated_at TIMESTAMP,
|
||||
deleted_at TIMESTAMP,
|
||||
UNIQUE (cgrid)
|
||||
UNIQUE (cgrid, run_id)
|
||||
);
|
||||
;
|
||||
DROP INDEX IF EXISTS deleted_at_cp_idx;
|
||||
|
||||
@@ -253,10 +253,7 @@ func cdrLogAction(acc *Account, sq *StatsQueueTriggered, a *Action, acs Actions)
|
||||
if cdrStorage == nil { // Only save if the cdrStorage is defined
|
||||
continue
|
||||
}
|
||||
if err := cdrStorage.SetCdr(cdr); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cdrStorage.SetRatedCdr(cdr); err != nil {
|
||||
if err := cdrStorage.SetCDR(cdr, true); err != nil {
|
||||
return err
|
||||
}
|
||||
// FixMe
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package engine
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"path"
|
||||
@@ -33,6 +34,8 @@ var actsLclCfg *config.CGRConfig
|
||||
var actsLclRpc *rpc.Client
|
||||
var actsLclCfgPath = path.Join(*dataDir, "conf", "samples", "actions")
|
||||
|
||||
var waitRater = flag.Int("wait_rater", 100, "Number of miliseconds to wait for rater to start and cache")
|
||||
|
||||
func TestActionsLocalInitCfg(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
@@ -61,7 +64,7 @@ func TestActionsLocalStartEngine(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
if _, err := StartEngine(actsLclCfgPath, waitRater); err != nil {
|
||||
if _, err := StartEngine(actsLclCfgPath, *waitRater); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -129,7 +132,7 @@ func TestActionsLocalStopCgrEngine(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
if err := KillEngine(waitRater); err != nil {
|
||||
if err := KillEngine(*waitRater); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ import (
|
||||
|
||||
func NewCDRFromExternalCDR(extCdr *ExternalCDR, timezone string) (*CDR, error) {
|
||||
var err error
|
||||
cdr := &CDR{CGRID: extCdr.CGRID, OrderID: extCdr.OrderID, TOR: extCdr.TOR, OriginID: extCdr.OriginID, OriginHost: extCdr.OriginHost, Source: extCdr.Source,
|
||||
RequestType: extCdr.RequestType, Direction: extCdr.Direction, Tenant: extCdr.Tenant, Category: extCdr.Category, Account: extCdr.Account, Subject: extCdr.Subject,
|
||||
Destination: extCdr.Destination, Supplier: extCdr.Supplier, DisconnectCause: extCdr.DisconnectCause,
|
||||
RunID: extCdr.RunID, Cost: extCdr.Cost, Rated: extCdr.Rated}
|
||||
cdr := &CDR{CGRID: extCdr.CGRID, RunID: extCdr.RunID, OrderID: extCdr.OrderID, TOR: extCdr.TOR, OriginID: extCdr.OriginID, OriginHost: extCdr.OriginHost,
|
||||
Source: extCdr.Source, RequestType: extCdr.RequestType, Direction: extCdr.Direction, Tenant: extCdr.Tenant, Category: extCdr.Category,
|
||||
Account: extCdr.Account, Subject: extCdr.Subject, Destination: extCdr.Destination, Supplier: extCdr.Supplier,
|
||||
DisconnectCause: extCdr.DisconnectCause, CostSource: extCdr.CostSource, Cost: extCdr.Cost, Rated: extCdr.Rated}
|
||||
if cdr.SetupTime, err = utils.ParseTimeDetectLayout(extCdr.SetupTime, timezone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -93,16 +93,14 @@ type CDR struct {
|
||||
Supplier string // Supplier information when available
|
||||
DisconnectCause string // Disconnect cause of the event
|
||||
ExtraFields map[string]string // Extra fields to be stored in CDR
|
||||
CostSource string // The source of this cost
|
||||
Cost float64
|
||||
ExtraInfo string // Container for extra information related to this CDR, eg: populated with error reason in case of error on calculation
|
||||
CostDetails *CallCost // Attach the cost details to CDR when possible
|
||||
ExtraInfo string // Container for extra information related to this CDR, eg: populated with error reason in case of error on calculation
|
||||
Rated bool // Mark the CDR as rated so we do not process it during rating
|
||||
}
|
||||
|
||||
func (cdr *CDR) CostDetailsJson() string {
|
||||
if cdr.CostDetails == nil {
|
||||
return ""
|
||||
}
|
||||
mrshled, _ := json.Marshal(cdr.CostDetails)
|
||||
return string(mrshled)
|
||||
}
|
||||
@@ -494,11 +492,12 @@ func (cdr *CDR) ForkCdr(runId string, RequestTypeFld, directionFld, tenantFld, c
|
||||
|
||||
func (cdr *CDR) AsExternalCDR() *ExternalCDR {
|
||||
return &ExternalCDR{CGRID: cdr.CGRID,
|
||||
RunID: cdr.RunID,
|
||||
OrderID: cdr.OrderID,
|
||||
TOR: cdr.TOR,
|
||||
OriginID: cdr.OriginID,
|
||||
OriginHost: cdr.OriginHost,
|
||||
Source: cdr.Source,
|
||||
OriginID: cdr.OriginID,
|
||||
TOR: cdr.TOR,
|
||||
RequestType: cdr.RequestType,
|
||||
Direction: cdr.Direction,
|
||||
Tenant: cdr.Tenant,
|
||||
@@ -507,15 +506,17 @@ func (cdr *CDR) AsExternalCDR() *ExternalCDR {
|
||||
Subject: cdr.Subject,
|
||||
Destination: cdr.Destination,
|
||||
SetupTime: cdr.SetupTime.Format(time.RFC3339),
|
||||
PDD: cdr.FieldAsString(&utils.RSRField{Id: utils.PDD}),
|
||||
AnswerTime: cdr.AnswerTime.Format(time.RFC3339),
|
||||
Usage: cdr.FormatUsage(utils.SECONDS),
|
||||
PDD: cdr.FieldAsString(&utils.RSRField{Id: utils.PDD}),
|
||||
Supplier: cdr.Supplier,
|
||||
DisconnectCause: cdr.DisconnectCause,
|
||||
ExtraFields: cdr.ExtraFields,
|
||||
RunID: cdr.RunID,
|
||||
CostSource: cdr.CostSource,
|
||||
Cost: cdr.Cost,
|
||||
CostDetails: cdr.CostDetailsJson(),
|
||||
ExtraInfo: cdr.ExtraInfo,
|
||||
Rated: cdr.Rated,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,11 +700,12 @@ func (cdr *CDR) String() string {
|
||||
|
||||
type ExternalCDR struct {
|
||||
CGRID string
|
||||
RunID string
|
||||
OrderID int64
|
||||
TOR string
|
||||
OriginID string
|
||||
OriginHost string
|
||||
Source string
|
||||
OriginID string
|
||||
TOR string
|
||||
RequestType string
|
||||
Direction string
|
||||
Tenant string
|
||||
@@ -712,15 +714,16 @@ type ExternalCDR struct {
|
||||
Subject string
|
||||
Destination string
|
||||
SetupTime string
|
||||
PDD string
|
||||
AnswerTime string
|
||||
Usage string
|
||||
PDD string
|
||||
Supplier string
|
||||
DisconnectCause string
|
||||
ExtraFields map[string]string
|
||||
RunID string
|
||||
CostSource string
|
||||
Cost float64
|
||||
CostDetails string
|
||||
ExtraInfo string
|
||||
Rated bool // Mark the CDR as rated so we do not process it during mediation
|
||||
}
|
||||
|
||||
|
||||
@@ -474,7 +474,7 @@ func TestCDRAsExternalCDR(t *testing.T) {
|
||||
Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: "2013-11-07T08:42:20Z", AnswerTime: "2013-11-07T08:42:26Z", RunID: utils.DEFAULT_RUNID,
|
||||
Usage: "0.00000001", PDD: "7", Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01}
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, Cost: 1.01, CostDetails: "null"}
|
||||
if cdrOut := storCdr.AsExternalCDR(); !reflect.DeepEqual(expectOutCdr, cdrOut) {
|
||||
t.Errorf("Expected: %+v, received: %+v", expectOutCdr, cdrOut)
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ func (self *CdrServer) processCdr(cdr *CDR) (err error) {
|
||||
return err
|
||||
}
|
||||
if self.cgrCfg.CDRSStoreCdrs { // Store RawCDRs, this we do sync so we can reply with the status
|
||||
if err := self.cdrDb.SetCdr(cdr); err != nil { // Only original CDR stored in primary table, no derived
|
||||
if err := self.cdrDb.SetCDR(cdr, false); err != nil { // Only original CDR stored in primary table, no derived
|
||||
utils.Logger.Err(fmt.Sprintf("<CDRS> Storing primary CDR %+v, got error: %s", cdr, err.Error()))
|
||||
return err // Error is propagated back and we don't continue processing the CDR if we cannot store it
|
||||
}
|
||||
@@ -257,7 +257,7 @@ func (self *CdrServer) rateStoreStatsReplicate(cdr *CDR) error {
|
||||
}
|
||||
if self.cgrCfg.CDRSStoreCdrs { // Store CDRs
|
||||
// Store RatedCDR
|
||||
if err := self.cdrDb.SetRatedCdr(cdr); err != nil {
|
||||
if err := self.cdrDb.SetCDR(cdr, true); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<CDRS> Storing rated CDR %+v, got error: %s", cdr, err.Error()))
|
||||
}
|
||||
// Store CostDetails
|
||||
|
||||
@@ -415,7 +415,7 @@ type TBLCDRs struct {
|
||||
DisconnectCause string
|
||||
ExtraFields string
|
||||
Cost float64
|
||||
Timespans string
|
||||
CostDetails string
|
||||
CostSource string
|
||||
ExtraInfo string
|
||||
CreatedAt time.Time
|
||||
|
||||
177
engine/storage_cdrs_it_test.go
Normal file
177
engine/storage_cdrs_it_test.go
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
Rating system designed to be used in VoIP Carriers World
|
||||
Copyright (C) 2012-2015 ITsysCOM
|
||||
|
||||
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 engine
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"path"
|
||||
//"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var testIntegration = flag.Bool("integration", false, "Perform the tests in integration mode, not by default.") // This flag will be passed here via "go test -local" args
|
||||
|
||||
func TestITCDRsMySQL(t *testing.T) {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
cfg, err := config.NewCGRConfigFromFolder(path.Join(*dataDir, "conf", "samples", "storage", "mysql"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := InitStorDb(cfg); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
mysqlDb, err := NewMySQLStorage(cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass,
|
||||
cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns)
|
||||
if err != nil {
|
||||
t.Error("Error on opening database connection: ", err)
|
||||
}
|
||||
if err := testSetCDR(mysqlDb); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestITCDRsPSQL(t *testing.T) {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
cfg, err := config.NewCGRConfigFromFolder(path.Join(*dataDir, "conf", "samples", "storage", "postgres"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := InitStorDb(cfg); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
psqlDb, err := NewPostgresStorage(cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass,
|
||||
cfg.StorDBMaxOpenConns, cfg.StorDBMaxIdleConns)
|
||||
if err != nil {
|
||||
t.Error("Error on opening database connection: ", err)
|
||||
}
|
||||
if err := testSetCDR(psqlDb); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to populate CDRs and check if they were stored in storDb
|
||||
func testSetCDR(cdrStorage CdrStorage) error {
|
||||
rawCDR := &CDR{
|
||||
CGRID: utils.Sha1("testevent1", time.Date(2015, 12, 12, 14, 52, 0, 0, time.UTC).String()),
|
||||
RunID: utils.MetaRaw,
|
||||
OriginHost: "127.0.0.1",
|
||||
Source: "testSetCDRs",
|
||||
OriginID: "testevent1",
|
||||
TOR: utils.VOICE,
|
||||
RequestType: utils.META_PREPAID,
|
||||
Direction: utils.OUT,
|
||||
Tenant: "cgrates.org",
|
||||
Category: "call",
|
||||
Account: "1004",
|
||||
Subject: "1004",
|
||||
Destination: "1007",
|
||||
SetupTime: time.Date(2015, 12, 12, 14, 52, 0, 0, time.UTC),
|
||||
PDD: time.Duration(20) * time.Millisecond,
|
||||
AnswerTime: time.Date(2015, 12, 12, 14, 52, 20, 0, time.UTC),
|
||||
Usage: time.Duration(35) * time.Second,
|
||||
Supplier: "SUPPLIER1",
|
||||
DisconnectCause: "NORMAL_DISCONNECT",
|
||||
ExtraFields: map[string]string{"ExtraHeader1": "ExtraVal1", "ExtraHeader2": "ExtraVal2"},
|
||||
Cost: -1,
|
||||
}
|
||||
if err := cdrStorage.SetCDR(rawCDR, false); err != nil {
|
||||
return fmt.Errorf("rawCDR: %+v, SetCDR err: %s", rawCDR, err.Error())
|
||||
}
|
||||
if cdrs, _, err := cdrStorage.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{rawCDR.CGRID}, RunIDs: []string{utils.MetaRaw}}); err != nil {
|
||||
return fmt.Errorf("rawCDR: %+v, GetCDRs err: %s", rawCDR, err.Error())
|
||||
} else if len(cdrs) != 1 {
|
||||
return fmt.Errorf("rawCDR %+v, Unexpected number of CDRs returned: %d", rawCDR, len(cdrs))
|
||||
}
|
||||
ratedCDR := &CDR{
|
||||
CGRID: utils.Sha1("testevent1", time.Date(2015, 12, 12, 14, 52, 0, 0, time.UTC).String()),
|
||||
RunID: utils.META_DEFAULT,
|
||||
OriginHost: "127.0.0.1",
|
||||
Source: "testSetCDRs",
|
||||
OriginID: "testevent1",
|
||||
TOR: utils.VOICE,
|
||||
RequestType: utils.META_PREPAID,
|
||||
Direction: utils.OUT,
|
||||
Tenant: "cgrates.org",
|
||||
Category: "call",
|
||||
Account: "1004",
|
||||
Subject: "1004",
|
||||
Destination: "1007",
|
||||
SetupTime: time.Date(2015, 12, 12, 14, 52, 0, 0, time.UTC),
|
||||
PDD: time.Duration(20) * time.Millisecond,
|
||||
AnswerTime: time.Date(2015, 12, 12, 14, 52, 20, 0, time.UTC),
|
||||
Usage: time.Duration(35) * time.Second,
|
||||
Supplier: "SUPPLIER1",
|
||||
DisconnectCause: "NORMAL_DISCONNECT",
|
||||
ExtraFields: map[string]string{"ExtraHeader1": "ExtraVal1", "ExtraHeader2": "ExtraVal2"},
|
||||
CostSource: "testSetCDRs",
|
||||
Cost: 0.17,
|
||||
}
|
||||
if err := cdrStorage.SetCDR(ratedCDR, false); err != nil {
|
||||
return fmt.Errorf("ratedCDR: %+v, SetCDR err: %s", ratedCDR, err.Error())
|
||||
}
|
||||
if cdrs, _, err := cdrStorage.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{ratedCDR.CGRID}, RunIDs: []string{ratedCDR.RunID}}); err != nil {
|
||||
return fmt.Errorf("ratedCDR: %+v, GetCDRs err: %s", ratedCDR, err.Error())
|
||||
} else if len(cdrs) != 1 {
|
||||
return fmt.Errorf("ratedCDR %+v, Unexpected number of CDRs returned: %d", ratedCDR, len(cdrs))
|
||||
} else {
|
||||
if cdrs[0].RunID != ratedCDR.RunID {
|
||||
return fmt.Errorf("Unexpected ratedCDR received: %+v", cdrs[0])
|
||||
}
|
||||
if cdrs[0].RequestType != ratedCDR.RequestType {
|
||||
return fmt.Errorf("Unexpected ratedCDR received: %+v", cdrs[0])
|
||||
}
|
||||
if cdrs[0].Cost != ratedCDR.Cost {
|
||||
return fmt.Errorf("Unexpected ratedCDR received: %+v", cdrs[0])
|
||||
}
|
||||
}
|
||||
// Make sure duplicating does not work
|
||||
if err := cdrStorage.SetCDR(ratedCDR, false); err == nil {
|
||||
return fmt.Errorf("Duplicating ratedCDR: %+v works", ratedCDR)
|
||||
}
|
||||
ratedCDR.RequestType = utils.META_RATED
|
||||
ratedCDR.Cost = 0.34
|
||||
if err := cdrStorage.SetCDR(ratedCDR, true); err != nil {
|
||||
return fmt.Errorf("Rerating ratedCDR: %+v, SetCDR err: %s", ratedCDR, err.Error())
|
||||
}
|
||||
if cdrs, _, err := cdrStorage.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{ratedCDR.CGRID}, RunIDs: []string{ratedCDR.RunID}}); err != nil {
|
||||
return fmt.Errorf("Rerating ratedCDR: %+v, GetCDRs err: %s", ratedCDR, err.Error())
|
||||
} else if len(cdrs) != 1 {
|
||||
return fmt.Errorf("Rerating ratedCDR %+v, Unexpected number of CDRs returned: %d", ratedCDR, len(cdrs))
|
||||
} else {
|
||||
if cdrs[0].RunID != ratedCDR.RunID {
|
||||
return fmt.Errorf("Unexpected ratedCDR received after rerating: %+v", cdrs[0])
|
||||
}
|
||||
if cdrs[0].RequestType != ratedCDR.RequestType {
|
||||
return fmt.Errorf("Unexpected ratedCDR received after rerating: %+v", cdrs[0])
|
||||
}
|
||||
if cdrs[0].Cost != ratedCDR.Cost {
|
||||
return fmt.Errorf("Unexpected ratedCDR received after rerating: %+v", cdrs[0])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -94,8 +94,7 @@ type AccountingStorage interface {
|
||||
|
||||
type CdrStorage interface {
|
||||
Storage
|
||||
SetCdr(*CDR) error
|
||||
SetRatedCdr(*CDR) error
|
||||
SetCDR(*CDR, bool) error
|
||||
LogCallCost(cgrid, source, runid string, cc *CallCost) error
|
||||
GetCallCostLog(cgrid, source, runid string) (*CallCost, error)
|
||||
GetCDRs(*utils.CDRsFilter) ([]*CDR, int64, error)
|
||||
|
||||
@@ -1,967 +0,0 @@
|
||||
/*
|
||||
Rating system designed to be used in VoIP Carriers World
|
||||
Copyright (C) 2012-2015 ITsysCOM
|
||||
|
||||
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 engine
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var mongoDb *MongoStorage
|
||||
|
||||
func TestMongoCreateTables(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
cgrConfig, _ := config.NewDefaultCGRConfig()
|
||||
var err error
|
||||
if mongoDb, err = NewMongoStorage("localhost", "27017", cgrConfig.StorDBName, cgrConfig.StorDBUser, cgrConfig.StorDBPass); err != nil {
|
||||
t.Error("Error on opening database connection: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPTiming(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
tm := TpTiming{Tpid: utils.TEST_SQL, Tag: "ALWAYS", Time: "00:00:00"}
|
||||
if err := mongoDb.SetTpTimings([]TpTiming{tm}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mongoDb.GetTpTimings(utils.TEST_SQL, tm.Tag); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(tm, tmgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[0])
|
||||
}
|
||||
// Update
|
||||
tm.Time = "00:00:01"
|
||||
if err := mongoDb.SetTpTimings([]TpTiming{tm}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mongoDb.GetTpTimings(utils.TEST_SQL, tm.Tag); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(tm, tmgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPDestination(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
dst := []TpDestination{
|
||||
TpDestination{Tpid: utils.TEST_SQL, Tag: utils.TEST_SQL, Prefix: "+49"},
|
||||
TpDestination{Tpid: utils.TEST_SQL, Tag: utils.TEST_SQL, Prefix: "+49151"},
|
||||
TpDestination{Tpid: utils.TEST_SQL, Tag: utils.TEST_SQL, Prefix: "+49176"},
|
||||
}
|
||||
if err := mongoDb.SetTpDestinations(dst); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
storData, err := mongoDb.GetTpDestinations(utils.TEST_SQL, utils.TEST_SQL)
|
||||
dsts, err := TpDestinations(storData).GetDestinations()
|
||||
expected := &Destination{Id: utils.TEST_SQL, Prefixes: []string{"+49", "+49151", "+49176"}}
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(*expected, *dsts[utils.TEST_SQL]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", expected, dsts[utils.TEST_SQL])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPRates(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
RT_ID := "RT_1"
|
||||
rtSlots := []*utils.RateSlot{
|
||||
&utils.RateSlot{ConnectFee: 0.02, Rate: 0.01, RateUnit: "60s", RateIncrement: "60s", GroupIntervalStart: "0s"},
|
||||
&utils.RateSlot{ConnectFee: 0.00, Rate: 0.005, RateUnit: "60s", RateIncrement: "1s", GroupIntervalStart: "60s"},
|
||||
}
|
||||
for _, rs := range rtSlots {
|
||||
rs.SetDurations()
|
||||
}
|
||||
rates := &utils.TPRate{
|
||||
TPid: utils.TEST_SQL,
|
||||
RateId: RT_ID,
|
||||
RateSlots: rtSlots,
|
||||
}
|
||||
mRates := APItoModelRate(rates)
|
||||
if err := mongoDb.SetTpRates(mRates); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rts, err := mongoDb.GetTpRates(utils.TEST_SQL, RT_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mRates[0], rts[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mRates, rts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPDestinationRates(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
DR_ID := "DR_1"
|
||||
dr := &utils.DestinationRate{DestinationId: "DST_1", RateId: "RT_1", RoundingMethod: "*up", RoundingDecimals: 4}
|
||||
|
||||
eDrs := &utils.TPDestinationRate{TPid: utils.TEST_SQL, DestinationRateId: DR_ID, DestinationRates: []*utils.DestinationRate{dr}}
|
||||
mdrs := APItoModelDestinationRate(eDrs)
|
||||
if err := mongoDb.SetTpDestinationRates(mdrs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if drs, err := mongoDb.GetTpDestinationRates(utils.TEST_SQL, DR_ID, nil); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mdrs[0], drs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mdrs, drs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPRatingPlans(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
RP_ID := "RP_1"
|
||||
rbBinding := &utils.TPRatingPlanBinding{DestinationRatesId: "DR_1", TimingId: "TM_1", Weight: 10.0}
|
||||
rp := &utils.TPRatingPlan{
|
||||
TPid: utils.TEST_SQL,
|
||||
RatingPlanId: RP_ID,
|
||||
RatingPlanBindings: []*utils.TPRatingPlanBinding{rbBinding},
|
||||
}
|
||||
mrp := APItoModelRatingPlan(rp)
|
||||
if err := mongoDb.SetTpRatingPlans(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if drps, err := mongoDb.GetTpRatingPlans(utils.TEST_SQL, RP_ID, nil); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mrp[0], drps[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mrp, drps)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPRatingProfiles(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RP_1"}}
|
||||
rp := &utils.TPRatingProfile{TPid: utils.TEST_SQL, LoadId: utils.TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras}
|
||||
mrp := APItoModelRatingProfile(rp)
|
||||
if err := mongoDb.SetTpRatingProfiles(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := mongoDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mrp[0], rps[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mrp, rps)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPSharedGroups(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
SG_ID := "SG_1"
|
||||
tpSgs := &utils.TPSharedGroups{
|
||||
TPid: utils.TEST_SQL,
|
||||
SharedGroupsId: SG_ID,
|
||||
SharedGroups: []*utils.TPSharedGroup{
|
||||
&utils.TPSharedGroup{Account: "dan", Strategy: "*lowest_first", RatingSubject: "lowest_rates"},
|
||||
},
|
||||
}
|
||||
mSgs := APItoModelSharedGroup(tpSgs)
|
||||
if err := mongoDb.SetTpSharedGroups(mSgs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if sgs, err := mongoDb.GetTpSharedGroups(utils.TEST_SQL, SG_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mSgs[0], sgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mSgs, sgs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPcdrstats(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
CS_ID := "cdrsTATS_1"
|
||||
setCS := &utils.TPCdrStats{
|
||||
TPid: utils.TEST_SQL,
|
||||
CdrStatsId: CS_ID,
|
||||
CdrStats: []*utils.TPCdrStat{
|
||||
&utils.TPCdrStat{QueueLength: "10", TimeWindow: "10m", Metrics: "ASR", Tenants: "cgrates.org", Categories: "call"},
|
||||
},
|
||||
}
|
||||
mcs := APItoModelCdrStat(setCS)
|
||||
if err := mongoDb.SetTpCdrStats(mcs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if cs, err := mongoDb.GetTpCdrStats(utils.TEST_SQL, CS_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mcs[0], cs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mcs, cs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPDerivedChargers(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
dc := &utils.TPDerivedCharger{RunId: utils.DEFAULT_RUNID, ReqTypeField: "^" + utils.META_PREPAID, AccountField: "^rif", SubjectField: "^rif",
|
||||
UsageField: "cgr_duration", SupplierField: "^supplier1"}
|
||||
dcs := &utils.TPDerivedChargers{TPid: utils.TEST_SQL, Direction: utils.OUT, Tenant: "cgrates.org", Category: "call", Account: "dan", Subject: "dan", DerivedChargers: []*utils.TPDerivedCharger{dc}}
|
||||
|
||||
mdcs := APItoModelDerivedCharger(dcs)
|
||||
if err := mongoDb.SetTpDerivedChargers(mdcs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rDCs, err := mongoDb.GetTpDerivedChargers(&mdcs[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mdcs[0], rDCs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mdcs, rDCs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPActions(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
ACTS_ID := "PREPAID_10"
|
||||
acts := []*utils.TPAction{
|
||||
&utils.TPAction{Identifier: "*topup_reset", BalanceType: "*monetary", Directions: "*out", Units: 10, ExpiryTime: "*unlimited",
|
||||
DestinationIds: "*any", BalanceWeight: 10, Weight: 10}}
|
||||
tpActions := &utils.TPActions{TPid: utils.TEST_SQL, ActionsId: ACTS_ID, Actions: acts}
|
||||
mas := APItoModelAction(tpActions)
|
||||
if err := mongoDb.SetTpActions(mas); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rTpActs, err := mongoDb.GetTpActions(utils.TEST_SQL, ACTS_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mas[0], rTpActs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mas, rTpActs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoTPActionTimings(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
AP_ID := "AP_1"
|
||||
ap := &utils.TPActionPlan{
|
||||
TPid: utils.TEST_SQL,
|
||||
ActionPlanId: AP_ID,
|
||||
ActionPlan: []*utils.TPActionTiming{&utils.TPActionTiming{ActionsId: "ACTS_1", TimingId: "TM_1", Weight: 10.0}},
|
||||
}
|
||||
maps := APItoModelActionPlan(ap)
|
||||
if err := mongoDb.SetTpActionPlans(maps); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rAP, err := mongoDb.GetTpActionPlans(utils.TEST_SQL, AP_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(maps[0], rAP[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", maps, rAP)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTPActionTriggers(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
atrg := &utils.TPActionTrigger{
|
||||
Id: "MY_FIRST_ATGR",
|
||||
BalanceType: "*monetary",
|
||||
BalanceDirections: "*out",
|
||||
ThresholdType: "*min_balance",
|
||||
ThresholdValue: 2.0,
|
||||
Recurrent: true,
|
||||
BalanceDestinationIds: "*any",
|
||||
Weight: 10.0,
|
||||
ActionsId: "LOG_BALANCE",
|
||||
}
|
||||
atrgs := &utils.TPActionTriggers{
|
||||
TPid: utils.TEST_SQL,
|
||||
ActionTriggersId: utils.TEST_SQL,
|
||||
ActionTriggers: []*utils.TPActionTrigger{atrg},
|
||||
}
|
||||
matrg := APItoModelActionTrigger(atrgs)
|
||||
if err := mongoDb.SetTpActionTriggers(matrg); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
}
|
||||
if rcvMpAtrgs, err := mongoDb.GetTpActionTriggers(utils.TEST_SQL, utils.TEST_SQL); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
} else if !modelEqual(matrg[0], rcvMpAtrgs[0]) {
|
||||
t.Errorf("Expecting: %v, received: %v", matrg, rcvMpAtrgs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetGetTpAccountActions(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
aa := &utils.TPAccountActions{TPid: utils.TEST_SQL, Tenant: "cgrates.org", Account: "1001", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}
|
||||
maa := APItoModelAccountAction(aa)
|
||||
if err := mongoDb.SetTpAccountActions([]TpAccountAction{*maa}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := mongoDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(*maa, aas[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", maa, aas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoGetTPIds(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
eTPIds := []string{utils.TEST_SQL}
|
||||
if tpIds, err := mongoDb.GetTpIds(); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(eTPIds, tpIds) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eTPIds, tpIds)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoRemoveTPData(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
// Create Timings
|
||||
tm := &utils.ApierTPTiming{TPid: utils.TEST_SQL, TimingId: "ALWAYS", Time: "00:00:00"}
|
||||
tms := APItoModelTiming(tm)
|
||||
if err := mongoDb.SetTpTimings([]TpTiming{*tms}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mongoDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(tmgs) == 0 {
|
||||
t.Error("Could not store TPTiming")
|
||||
}
|
||||
// Remove Timings
|
||||
if err := mongoDb.RemTpData(utils.TBL_TP_TIMINGS, utils.TEST_SQL, map[string]string{"tag": tm.TimingId}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mongoDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(tmgs) != 0 {
|
||||
t.Errorf("Timings should be empty, got instead: %+v", tmgs)
|
||||
}
|
||||
// Create RatingProfile
|
||||
ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RETAIL1"}}
|
||||
rp := &utils.TPRatingProfile{TPid: utils.TEST_SQL, LoadId: utils.TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras}
|
||||
mrp := APItoModelRatingProfile(rp)
|
||||
if err := mongoDb.SetTpRatingProfiles(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := mongoDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rps) == 0 {
|
||||
t.Error("Could not store TPRatingProfile")
|
||||
}
|
||||
// Remove RatingProfile
|
||||
if err := mongoDb.RemTpData(utils.TBL_TP_RATE_PROFILES, rp.TPid, map[string]string{"loadid": rp.LoadId, "direction": rp.Direction, "tenant": rp.Tenant, "category": rp.Category, "subject": rp.Subject}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := mongoDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(rps) != 0 {
|
||||
t.Errorf("RatingProfiles different than 0: %+v", rps)
|
||||
}
|
||||
// Create AccountActions
|
||||
aa := &utils.TPAccountActions{TPid: utils.TEST_SQL, LoadId: utils.TEST_SQL, Tenant: "cgrates.org", Account: "1001", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}
|
||||
maa := APItoModelAccountAction(aa)
|
||||
if err := mongoDb.SetTpAccountActions([]TpAccountAction{*maa}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := mongoDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(aas) == 0 {
|
||||
t.Error("Could not create TPAccountActions")
|
||||
}
|
||||
// Remove AccountActions
|
||||
if err := mongoDb.RemTpData(utils.TBL_TP_ACCOUNT_ACTIONS, aa.TPid, map[string]string{"loadid": aa.LoadId, "tenant": aa.Tenant, "account": aa.Account}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := mongoDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aas) != 0 {
|
||||
t.Errorf("Non empty account actions: %+v", aas)
|
||||
}
|
||||
// Create again so we can test complete TP removal
|
||||
if err := mongoDb.SetTpTimings([]TpTiming{*tms}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mongoDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(tmgs) == 0 {
|
||||
t.Error("Could not store TPTiming")
|
||||
}
|
||||
// Create RatingProfile
|
||||
if err := mongoDb.SetTpRatingProfiles(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := mongoDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rps) == 0 {
|
||||
t.Error("Could not store TPRatingProfile")
|
||||
}
|
||||
// Create AccountActions
|
||||
if err := mongoDb.SetTpAccountActions([]TpAccountAction{*maa}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := mongoDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(aas) == 0 {
|
||||
t.Error("Could not create TPAccountActions")
|
||||
}
|
||||
// Remove TariffPlan completely
|
||||
if err := mongoDb.RemTpData("", utils.TEST_SQL, nil); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
// Make sure we have removed it
|
||||
if tms, err := mongoDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(tms) != 0 {
|
||||
t.Errorf("Non empty timings: %+v", tms)
|
||||
}
|
||||
if rpfs, err := mongoDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(rpfs) != 0 {
|
||||
t.Errorf("Non empty rpfs: %+v", rpfs)
|
||||
}
|
||||
if aas, err := mongoDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aas) != 0 {
|
||||
t.Errorf("Non empty account actions: %+v", aas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
cgrCdr1 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa1", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED,
|
||||
utils.DIRECTION: "*out", utils.TENANT: "cgrates.org",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:20Z",
|
||||
utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "10s", utils.PDD: "4s", utils.SUPPLIER: "SUPPL1",
|
||||
"field_extr1": "val_extr1", "fieldextr2": "valextr2", utils.CDRSOURCE: utils.TEST_SQL}
|
||||
|
||||
cgrCdr2 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa2", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_PREPAID, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:22Z",
|
||||
utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "20", utils.PDD: "7s", utils.SUPPLIER: "SUPPL1",
|
||||
"field_extr1": "val_extr1", "fieldextr2": "valextr2", "Source": utils.TEST_SQL}
|
||||
|
||||
cgrCdr3 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa3", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org",
|
||||
utils.CATEGORY: "premium_call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "1001", utils.SETUP_TIME: "2013-11-07T08:42:24Z",
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "60s", utils.PDD: "4s", utils.SUPPLIER: "SUPPL1",
|
||||
"field_extr1": "val_extr1", "fieldextr2": "valextr2", "Source": utils.TEST_SQL}
|
||||
|
||||
cgrCdr4 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa4", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_PSEUDOPREPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "+4986517174964", utils.SETUP_TIME: "2013-11-07T08:42:21Z",
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "1m2s", utils.PDD: "4s", utils.SUPPLIER: "SUPPL1",
|
||||
"field_extr1": "val_extr1", "fieldextr2": "valextr2", "Source": utils.TEST_SQL}
|
||||
|
||||
cgrCdr5 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa5", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_POSTPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "+4986517174963", utils.SETUP_TIME: "2013-11-07T08:42:25Z",
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "15s", utils.PDD: "7s", utils.SUPPLIER: "SUPPL1",
|
||||
"field_extr1": "val_extr1", "fieldextr2": "valextr2", "Source": utils.TEST_SQL}
|
||||
|
||||
for _, cdr := range []*CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} {
|
||||
if err := mongoDb.SetCdr(cdr.AsStoredCdr("")); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
strCdr1 := &CDR{TOR: utils.VOICE, OriginID: "bbb1", OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr1.CGRID = utils.Sha1(strCdr1.OriginID, strCdr1.SetupTime.String())
|
||||
strCdr2 := &CDR{TOR: utils.VOICE, OriginID: "bbb2", OriginHost: "192.168.1.2", Source: "UNKNOWN2", RequestType: utils.META_PREPAID,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(12) * time.Second, PDD: time.Duration(4) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 0.201}
|
||||
strCdr2.CGRID = utils.Sha1(strCdr2.OriginID, strCdr2.SetupTime.String())
|
||||
strCdr3 := &CDR{TOR: utils.VOICE, OriginID: "bbb3", OriginHost: "192.168.1.1", Source: utils.TEST_SQL, RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1000", Destination: "+4986517174963",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(2) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr3.CGRID = utils.Sha1(strCdr3.OriginID, strCdr3.SetupTime.String())
|
||||
|
||||
for _, cdr := range []*CDR{strCdr1, strCdr2, strCdr3} {
|
||||
if err := mongoDb.SetCdr(cdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoSetRatedCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
strCdr1 := &CDR{TOR: utils.VOICE, OriginID: "bbb1", OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr1.CGRID = utils.Sha1(strCdr1.OriginID, strCdr1.SetupTime.String())
|
||||
strCdr2 := &CDR{TOR: utils.VOICE, OriginID: "bbb2", OriginHost: "192.168.1.2", Source: "UNKNOWN", RequestType: utils.META_PREPAID,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(12) * time.Second, PDD: time.Duration(7) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 0.201}
|
||||
strCdr2.CGRID = utils.Sha1(strCdr2.OriginID, strCdr2.SetupTime.String())
|
||||
strCdr3 := &CDR{TOR: utils.VOICE, OriginID: "bbb3", OriginHost: "192.168.1.1", Source: utils.TEST_SQL, RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1002", Destination: "+4986517174964",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(2) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: "wholesale_run", Cost: 1.201}
|
||||
strCdr3.CGRID = utils.Sha1(strCdr3.OriginID, strCdr3.SetupTime.String())
|
||||
|
||||
for _, cdr := range []*CDR{strCdr1, strCdr2, strCdr3} {
|
||||
if err := mongoDb.SetRatedCdr(cdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoCallCost(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
CGRID := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
cc := &CallCost{
|
||||
Direction: "*out",
|
||||
Category: "call",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "91001",
|
||||
Account: "8001",
|
||||
Destination: "1002",
|
||||
TOR: utils.VOICE,
|
||||
Timespans: []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 13, 40, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC),
|
||||
},
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 10, 13, 41, 30, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := mongoDb.LogCallCost(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID, cc); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if ccRcv, err := mongoDb.GetCallCostLog(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if cc.Cost != ccRcv.Cost {
|
||||
t.Errorf("Expecting call cost:\n%+v,\nreceived:\n%+v", cc.Timespans[0], ccRcv.Timespans[0])
|
||||
}
|
||||
// UPDATE test here
|
||||
cc.Category = "premium_call"
|
||||
if err := mongoDb.LogCallCost(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID, cc); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if ccRcv, err := mongoDb.GetCallCostLog(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if cc.Cost != ccRcv.Cost {
|
||||
t.Errorf("Expecting call cost: %v, received: %v", cc, ccRcv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoGetcdrs(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
var timeStart, timeEnd time.Time
|
||||
// All cdrs, no filter
|
||||
if cdrs, _, err := mongoDb.GetCDRs(new(utils.CDRsFilter)); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 20 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Count ALL
|
||||
if cdrs, count, err := mongoDb.GetCDRs(&utils.CDRsFilter{Count: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 0 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
} else if count != 20 {
|
||||
t.Error("Unexpected count of cdrs returned: ", count)
|
||||
}
|
||||
// Limit 5
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Paginator: utils.Paginator{Limit: utils.IntPointer(5), Offset: utils.IntPointer(0)}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 5 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Offset 5
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Paginator: utils.Paginator{Limit: utils.IntPointer(5), Offset: utils.IntPointer(0)}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 5 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Offset with limit 2
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Paginator: utils.Paginator{Limit: utils.IntPointer(2), Offset: utils.IntPointer(5)}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 2 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on CGRIDs
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 3 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Count on CGRIDS
|
||||
if _, count, err := mongoDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, Count: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if count != 3 {
|
||||
t.Error("Unexpected count of cdrs returned: ", count)
|
||||
}
|
||||
// Filter on CGRIDs plus RequestType
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, RequestTypes: []string{utils.META_PREPAID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 1 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Count on multiple filter
|
||||
if _, count, err := mongoDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, RequestTypes: []string{utils.META_PREPAID}, Count: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if count != 1 {
|
||||
t.Error("Unexpected count of cdrs returned: ", count)
|
||||
}
|
||||
// Filter on runId
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{RunIDs: []string{utils.DEFAULT_RUNID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 14 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on TOR
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{TORs: []string{utils.SMS}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 0 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on multiple TOR
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{TORs: []string{utils.SMS, utils.VOICE}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 15 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on OriginHost
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{OriginHosts: []string{"192.168.1.2"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 3 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on multiple OriginHost
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{OriginHosts: []string{"192.168.1.1", "192.168.1.2"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 15 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on Source
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Sources: []string{"UNKNOWN"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 2 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on multiple Source
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Sources: []string{"UNKNOWN", "UNKNOWN2"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 2 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on RequestType
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{RequestTypes: []string{utils.META_PREPAID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 5 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on multiple RequestType
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{RequestTypes: []string{utils.META_PREPAID, utils.META_PSEUDOPREPAID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 6 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on direction
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Directions: []string{"*out"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 15 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on tenant
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Tenants: []string{"itsyscom.com"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 4 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on multiple tenants
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Tenants: []string{"itsyscom.com", "cgrates.org"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 15 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on category
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Categories: []string{"premium_call"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 1 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on multiple categories
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Categories: []string{"premium_call", "call"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 15 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on account
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Accounts: []string{"1002"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 6 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on multiple account
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Accounts: []string{"1001", "1002"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 13 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on subject
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Subjects: []string{"1000"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 1 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on multiple subject
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{Subjects: []string{"1000", "1002"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 6 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on destPrefix
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{DestinationPrefixes: []string{"+498651"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 4 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on multiple DestinationPrefixes
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{DestinationPrefixes: []string{"1001", "+498651"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 5 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on ignoreRated
|
||||
var OrderIDStart, OrderIDEnd int64 // Capture also OrderIDs for the next test
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{MaxCost: utils.Float64Pointer(0.0)}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 7 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
} else {
|
||||
for _, cdr := range cdrs {
|
||||
if cdr.OrderID < OrderIDStart {
|
||||
OrderIDStart = cdr.OrderID
|
||||
}
|
||||
if cdr.OrderID > OrderIDEnd {
|
||||
OrderIDEnd = cdr.OrderID
|
||||
}
|
||||
}
|
||||
}
|
||||
// Filter on OrderIDStart
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{OrderIDStart: OrderIDStart}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 20 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on OrderIDStart and OrderIDEnd
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{OrderIDStart: OrderIDStart, OrderIDEnd: OrderIDEnd}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 20 { // TODO: find mongo equivalent
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on timeStart
|
||||
timeStart = time.Date(2013, 11, 8, 8, 0, 0, 0, time.UTC)
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{AnswerTimeStart: &timeStart}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 6 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on timeStart and timeEnd
|
||||
timeEnd = time.Date(2013, 12, 1, 8, 0, 0, 0, time.UTC)
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 2 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on minPDD
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{MinPDD: utils.Float64Pointer(float64(3 * time.Second))}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 7 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on maxPDD
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{MaxPDD: utils.Float64Pointer(float64(3 * time.Second))}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 13 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on minPDD, maxPDD
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{MinPDD: utils.Float64Pointer(float64(3 * time.Second)), MaxPDD: utils.Float64Pointer(float64(5 * time.Second))}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 4 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Combined filter
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{RequestTypes: []string{utils.META_RATED}, AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 1 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
// Filter on ignoreDerived
|
||||
if cdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd, FilterOnRated: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 2 { // ToDo: Recheck this value
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMongoRemCDRs(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
CGRIDB1 := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
if err := mongoDb.RemCDRs([]string{CGRIDB1}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if cdrs, _, err := mongoDb.GetCDRs(new(utils.CDRsFilter)); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 20 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
tm, _ := utils.ParseTimeDetectLayout("2013-11-08T08:42:20Z", "")
|
||||
CGRIDA1 := utils.Sha1("aaa1", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-08T08:42:22Z", "")
|
||||
CGRIDA2 := utils.Sha1("aaa2", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:24Z", "")
|
||||
CGRIDA3 := utils.Sha1("aaa3", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:21Z", "")
|
||||
CGRIDA4 := utils.Sha1("aaa4", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:25Z", "")
|
||||
CGRIDA5 := utils.Sha1("aaa5", tm.String())
|
||||
CGRIDB2 := utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
CGRIDB3 := utils.Sha1("bbb3", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
if err := mongoDb.RemCDRs([]string{CGRIDA1, CGRIDA2, CGRIDA3, CGRIDA4, CGRIDA5,
|
||||
CGRIDB2, CGRIDB3}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if cdrs, _, err := mongoDb.GetCDRs(new(utils.CDRsFilter)); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(cdrs) != 20 {
|
||||
t.Error("Unexpected number of cdrs returned: ", len(cdrs))
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that what we get is what we set
|
||||
func TestMongoStoreRestoreCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
strCdr := &CDR{TOR: utils.VOICE, OriginID: "ccc1", OriginHost: "192.168.1.1", Source: "TEST_CDR", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr.CGRID = utils.Sha1(strCdr.OriginID, strCdr.SetupTime.String())
|
||||
if err := mongoDb.SetCdr(strCdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if err := mongoDb.SetRatedCdr(strCdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
// Check RawCdr
|
||||
if rcvcdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{strCdr.CGRID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rcvcdrs) != 1 {
|
||||
t.Errorf("Unexpected cdrs returned: %+v", rcvcdrs)
|
||||
} else {
|
||||
rcvCdr := rcvcdrs[0]
|
||||
if strCdr.CGRID != rcvCdr.CGRID ||
|
||||
strCdr.TOR != rcvCdr.TOR ||
|
||||
strCdr.OriginID != rcvCdr.OriginID ||
|
||||
strCdr.OriginHost != rcvCdr.OriginHost ||
|
||||
strCdr.RequestType != rcvCdr.RequestType ||
|
||||
strCdr.Direction != rcvCdr.Direction ||
|
||||
strCdr.Tenant != rcvCdr.Tenant ||
|
||||
strCdr.Category != rcvCdr.Category ||
|
||||
strCdr.Account != rcvCdr.Account ||
|
||||
strCdr.Subject != rcvCdr.Subject ||
|
||||
strCdr.Destination != rcvCdr.Destination ||
|
||||
!strCdr.SetupTime.Equal(rcvCdr.SetupTime) ||
|
||||
!strCdr.AnswerTime.Equal(rcvCdr.AnswerTime) ||
|
||||
strCdr.Usage != rcvCdr.Usage ||
|
||||
strCdr.PDD != rcvCdr.PDD ||
|
||||
strCdr.Supplier != rcvCdr.Supplier ||
|
||||
strCdr.DisconnectCause != rcvCdr.DisconnectCause ||
|
||||
!reflect.DeepEqual(strCdr.ExtraFields, rcvCdr.ExtraFields) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", strCdr, rcvcdrs[0])
|
||||
}
|
||||
}
|
||||
// Check RatedCdr
|
||||
if rcvcdrs, _, err := mongoDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{strCdr.CGRID}, FilterOnRated: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rcvcdrs) != 1 {
|
||||
t.Errorf("Unexpected cdrs returned: %+v", rcvcdrs)
|
||||
} else {
|
||||
rcvCdr := rcvcdrs[0]
|
||||
if strCdr.CGRID != rcvCdr.CGRID ||
|
||||
strCdr.TOR != rcvCdr.TOR ||
|
||||
strCdr.OriginID != rcvCdr.OriginID ||
|
||||
strCdr.OriginHost != rcvCdr.OriginHost ||
|
||||
strCdr.RequestType != rcvCdr.RequestType ||
|
||||
strCdr.Direction != rcvCdr.Direction ||
|
||||
strCdr.Tenant != rcvCdr.Tenant ||
|
||||
strCdr.Category != rcvCdr.Category ||
|
||||
strCdr.Account != rcvCdr.Account ||
|
||||
strCdr.Subject != rcvCdr.Subject ||
|
||||
strCdr.Destination != rcvCdr.Destination ||
|
||||
//!strCdr.SetupTime.Equal(rcvCdr.SetupTime) || // FixMe
|
||||
//!strCdr.AnswerTime.Equal(rcvCdr.AnswerTime) || // FixMe
|
||||
strCdr.Usage != rcvCdr.Usage ||
|
||||
strCdr.PDD != rcvCdr.PDD ||
|
||||
strCdr.Supplier != rcvCdr.Supplier ||
|
||||
strCdr.DisconnectCause != rcvCdr.DisconnectCause ||
|
||||
strCdr.Cost != rcvCdr.Cost ||
|
||||
!reflect.DeepEqual(strCdr.ExtraFields, rcvCdr.ExtraFields) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", strCdr, rcvcdrs[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -716,12 +716,7 @@ func (ms *MongoStorage) GetCallCostLog(cgrid, source, runid string) (cc *CallCos
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) SetCdr(cdr *CDR) error {
|
||||
_, err := ms.db.C(colCdrs).Upsert(bson.M{"cgrid": cdr.CGRID, "mediationrunid": cdr.RunID}, cdr)
|
||||
return err
|
||||
}
|
||||
|
||||
func (ms *MongoStorage) SetRatedCdr(cdr *CDR) error {
|
||||
func (ms *MongoStorage) SetCDR(cdr *CDR, allowUpdate bool) error {
|
||||
_, err := ms.db.C(colCdrs).Upsert(bson.M{"cgrid": cdr.CGRID, "mediationrunid": cdr.RunID}, cdr)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,976 +0,0 @@
|
||||
/*
|
||||
Rating system designed to be used in VoIP Carriers World
|
||||
Copyright (C) 2012-2015 ITsysCOM
|
||||
|
||||
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 engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var mysqlDb *MySQLStorage
|
||||
|
||||
func TestMySQLCreateTables(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
cgrConfig, _ := config.NewDefaultCGRConfig()
|
||||
var err error
|
||||
if mysqlDb, err = NewMySQLStorage(cgrConfig.StorDBHost, cgrConfig.StorDBPort, cgrConfig.StorDBName, cgrConfig.StorDBUser, cgrConfig.StorDBPass,
|
||||
cgrConfig.StorDBMaxOpenConns, cgrConfig.StorDBMaxIdleConns); err != nil {
|
||||
t.Error("Error on opening database connection: ", err)
|
||||
return
|
||||
}
|
||||
for _, scriptName := range []string{utils.CREATE_CDRS_TABLES_SQL, utils.CREATE_TARIFFPLAN_TABLES_SQL} {
|
||||
if err := mysqlDb.CreateTablesFromScript(path.Join(*dataDir, "storage", utils.MYSQL, scriptName)); err != nil {
|
||||
t.Error("Error on mysqlDb creation: ", err.Error())
|
||||
return // No point in going further
|
||||
}
|
||||
}
|
||||
if _, err := mysqlDb.Db.Query(fmt.Sprintf("SELECT 1 from %s", utils.TBL_CDRS)); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPTiming(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
tm := TpTiming{Tpid: utils.TEST_SQL, Tag: "ALWAYS", Time: "00:00:00"}
|
||||
if err := mysqlDb.SetTpTimings([]TpTiming{tm}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mysqlDb.GetTpTimings(utils.TEST_SQL, tm.Tag); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(tm, tmgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[0])
|
||||
}
|
||||
// Update
|
||||
tm.Time = "00:00:01"
|
||||
if err := mysqlDb.SetTpTimings([]TpTiming{tm}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mysqlDb.GetTpTimings(utils.TEST_SQL, tm.Tag); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(tm, tmgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPDestination(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
dst := []TpDestination{
|
||||
TpDestination{Tpid: utils.TEST_SQL, Tag: utils.TEST_SQL, Prefix: "+49"},
|
||||
TpDestination{Tpid: utils.TEST_SQL, Tag: utils.TEST_SQL, Prefix: "+49151"},
|
||||
TpDestination{Tpid: utils.TEST_SQL, Tag: utils.TEST_SQL, Prefix: "+49176"},
|
||||
}
|
||||
if err := mysqlDb.SetTpDestinations(dst); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
storData, err := mysqlDb.GetTpDestinations(utils.TEST_SQL, utils.TEST_SQL)
|
||||
dsts, err := TpDestinations(storData).GetDestinations()
|
||||
expected := &Destination{Id: utils.TEST_SQL, Prefixes: []string{"+49", "+49151", "+49176"}}
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(*expected, *dsts[utils.TEST_SQL]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", expected, dsts[utils.TEST_SQL])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPRates(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
RT_ID := "RT_1"
|
||||
rtSlots := []*utils.RateSlot{
|
||||
&utils.RateSlot{ConnectFee: 0.02, Rate: 0.01, RateUnit: "60s", RateIncrement: "60s", GroupIntervalStart: "0s"},
|
||||
&utils.RateSlot{ConnectFee: 0.00, Rate: 0.005, RateUnit: "60s", RateIncrement: "1s", GroupIntervalStart: "60s"},
|
||||
}
|
||||
for _, rs := range rtSlots {
|
||||
rs.SetDurations()
|
||||
}
|
||||
rates := &utils.TPRate{
|
||||
TPid: utils.TEST_SQL,
|
||||
RateId: RT_ID,
|
||||
RateSlots: rtSlots,
|
||||
}
|
||||
mRates := APItoModelRate(rates)
|
||||
if err := mysqlDb.SetTpRates(mRates); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rts, err := mysqlDb.GetTpRates(utils.TEST_SQL, RT_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mRates[0], rts[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mRates, rts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPDestinationRates(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
DR_ID := "DR_1"
|
||||
dr := &utils.DestinationRate{DestinationId: "DST_1", RateId: "RT_1", RoundingMethod: "*up", RoundingDecimals: 4}
|
||||
|
||||
eDrs := &utils.TPDestinationRate{TPid: utils.TEST_SQL, DestinationRateId: DR_ID, DestinationRates: []*utils.DestinationRate{dr}}
|
||||
mdrs := APItoModelDestinationRate(eDrs)
|
||||
if err := mysqlDb.SetTpDestinationRates(mdrs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if drs, err := mysqlDb.GetTpDestinationRates(utils.TEST_SQL, DR_ID, nil); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mdrs[0], drs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mdrs, drs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPRatingPlans(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
RP_ID := "RP_1"
|
||||
rbBinding := &utils.TPRatingPlanBinding{DestinationRatesId: "DR_1", TimingId: "TM_1", Weight: 10.0}
|
||||
rp := &utils.TPRatingPlan{
|
||||
TPid: utils.TEST_SQL,
|
||||
RatingPlanId: RP_ID,
|
||||
RatingPlanBindings: []*utils.TPRatingPlanBinding{rbBinding},
|
||||
}
|
||||
mrp := APItoModelRatingPlan(rp)
|
||||
if err := mysqlDb.SetTpRatingPlans(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if drps, err := mysqlDb.GetTpRatingPlans(utils.TEST_SQL, RP_ID, nil); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mrp[0], drps[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mrp, drps)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPRatingProfiles(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RP_1"}}
|
||||
rp := &utils.TPRatingProfile{TPid: utils.TEST_SQL, LoadId: utils.TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras}
|
||||
mrp := APItoModelRatingProfile(rp)
|
||||
if err := mysqlDb.SetTpRatingProfiles(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := mysqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mrp[0], rps[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mrp, rps)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPSharedGroups(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
SG_ID := "SG_1"
|
||||
tpSgs := &utils.TPSharedGroups{
|
||||
TPid: utils.TEST_SQL,
|
||||
SharedGroupsId: SG_ID,
|
||||
SharedGroups: []*utils.TPSharedGroup{
|
||||
&utils.TPSharedGroup{Account: "dan", Strategy: "*lowest_first", RatingSubject: "lowest_rates"},
|
||||
},
|
||||
}
|
||||
mSgs := APItoModelSharedGroup(tpSgs)
|
||||
if err := mysqlDb.SetTpSharedGroups(mSgs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if sgs, err := mysqlDb.GetTpSharedGroups(utils.TEST_SQL, SG_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mSgs[0], sgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mSgs, sgs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPCdrStats(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
CS_ID := "CDRSTATS_1"
|
||||
setCS := &utils.TPCdrStats{
|
||||
TPid: utils.TEST_SQL,
|
||||
CdrStatsId: CS_ID,
|
||||
CdrStats: []*utils.TPCdrStat{
|
||||
&utils.TPCdrStat{QueueLength: "10", TimeWindow: "10m", Metrics: "ASR", Tenants: "cgrates.org", Categories: "call"},
|
||||
},
|
||||
}
|
||||
mcs := APItoModelCdrStat(setCS)
|
||||
if err := mysqlDb.SetTpCdrStats(mcs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if cs, err := mysqlDb.GetTpCdrStats(utils.TEST_SQL, CS_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mcs[0], cs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mcs, cs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPDerivedChargers(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
dc := &utils.TPDerivedCharger{RunId: utils.DEFAULT_RUNID, ReqTypeField: "^" + utils.META_PREPAID, AccountField: "^rif", SubjectField: "^rif",
|
||||
UsageField: "cgr_duration", SupplierField: "^supplier1"}
|
||||
dcs := &utils.TPDerivedChargers{TPid: utils.TEST_SQL, Direction: utils.OUT, Tenant: "cgrates.org", Category: "call", Account: "dan", Subject: "dan", DerivedChargers: []*utils.TPDerivedCharger{dc}}
|
||||
|
||||
mdcs := APItoModelDerivedCharger(dcs)
|
||||
if err := mysqlDb.SetTpDerivedChargers(mdcs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rDCs, err := mysqlDb.GetTpDerivedChargers(&mdcs[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mdcs[0], rDCs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mdcs, rDCs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPActions(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
ACTS_ID := "PREPAID_10"
|
||||
acts := []*utils.TPAction{
|
||||
&utils.TPAction{Identifier: "*topup_reset", BalanceType: "*monetary", Directions: "*out", Units: 10, ExpiryTime: "*unlimited",
|
||||
DestinationIds: "*any", BalanceWeight: 10, Weight: 10}}
|
||||
tpActions := &utils.TPActions{TPid: utils.TEST_SQL, ActionsId: ACTS_ID, Actions: acts}
|
||||
mas := APItoModelAction(tpActions)
|
||||
if err := mysqlDb.SetTpActions(mas); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rTpActs, err := mysqlDb.GetTpActions(utils.TEST_SQL, ACTS_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mas[0], rTpActs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mas, rTpActs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLTPActionTimings(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
AP_ID := "AP_1"
|
||||
ap := &utils.TPActionPlan{
|
||||
TPid: utils.TEST_SQL,
|
||||
ActionPlanId: AP_ID,
|
||||
ActionPlan: []*utils.TPActionTiming{&utils.TPActionTiming{ActionsId: "ACTS_1", TimingId: "TM_1", Weight: 10.0}},
|
||||
}
|
||||
maps := APItoModelActionPlan(ap)
|
||||
if err := mysqlDb.SetTpActionPlans(maps); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rAP, err := mysqlDb.GetTpActionPlans(utils.TEST_SQL, AP_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(maps[0], rAP[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", maps, rAP)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTPActionTriggers(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
atrg := &utils.TPActionTrigger{
|
||||
Id: "MY_FIRST_ATGR",
|
||||
BalanceType: "*monetary",
|
||||
BalanceDirections: "*out",
|
||||
ThresholdType: "*min_balance",
|
||||
ThresholdValue: 2.0,
|
||||
Recurrent: true,
|
||||
BalanceDestinationIds: "*any",
|
||||
Weight: 10.0,
|
||||
ActionsId: "LOG_BALANCE",
|
||||
}
|
||||
atrgs := &utils.TPActionTriggers{
|
||||
TPid: utils.TEST_SQL,
|
||||
ActionTriggersId: utils.TEST_SQL,
|
||||
ActionTriggers: []*utils.TPActionTrigger{atrg},
|
||||
}
|
||||
matrg := APItoModelActionTrigger(atrgs)
|
||||
if err := mysqlDb.SetTpActionTriggers(matrg); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
}
|
||||
if rcvMpAtrgs, err := mysqlDb.GetTpActionTriggers(utils.TEST_SQL, utils.TEST_SQL); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
} else if !modelEqual(matrg[0], rcvMpAtrgs[0]) {
|
||||
t.Errorf("Expecting: %v, received: %v", matrg, rcvMpAtrgs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetGetTpAccountActions(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
aa := &utils.TPAccountActions{TPid: utils.TEST_SQL, Tenant: "cgrates.org", Account: "1001",
|
||||
ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}
|
||||
maa := APItoModelAccountAction(aa)
|
||||
if err := mysqlDb.SetTpAccountActions([]TpAccountAction{*maa}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := mysqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(*maa, aas[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", maa, aas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLGetTPIds(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
eTPIds := []string{utils.TEST_SQL}
|
||||
if tpIds, err := mysqlDb.GetTpIds(); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(eTPIds, tpIds) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eTPIds, tpIds)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLRemoveTPData(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
// Create Timings
|
||||
tm := &utils.ApierTPTiming{TPid: utils.TEST_SQL, TimingId: "ALWAYS", Time: "00:00:00"}
|
||||
tms := APItoModelTiming(tm)
|
||||
if err := mysqlDb.SetTpTimings([]TpTiming{*tms}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mysqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(tmgs) == 0 {
|
||||
t.Error("Could not store TPTiming")
|
||||
}
|
||||
// Remove Timings
|
||||
if err := mysqlDb.RemTpData(utils.TBL_TP_TIMINGS, utils.TEST_SQL, map[string]string{"tag": tm.TimingId}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mysqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(tmgs) != 0 {
|
||||
t.Errorf("Timings should be empty, got instead: %+v", tmgs)
|
||||
}
|
||||
// Create RatingProfile
|
||||
ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RETAIL1"}}
|
||||
rp := &utils.TPRatingProfile{TPid: utils.TEST_SQL, LoadId: utils.TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras}
|
||||
mrp := APItoModelRatingProfile(rp)
|
||||
if err := mysqlDb.SetTpRatingProfiles(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := mysqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rps) == 0 {
|
||||
t.Error("Could not store TPRatingProfile")
|
||||
}
|
||||
// Remove RatingProfile
|
||||
if err := mysqlDb.RemTpData(utils.TBL_TP_RATE_PROFILES, rp.TPid, map[string]string{"loadid": rp.LoadId, "direction": rp.Direction, "tenant": rp.Tenant, "category": rp.Category, "subject": rp.Subject}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := mysqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(rps) != 0 {
|
||||
t.Errorf("RatingProfiles different than 0: %+v", rps)
|
||||
}
|
||||
// Create AccountActions
|
||||
aa := &utils.TPAccountActions{TPid: utils.TEST_SQL, LoadId: utils.TEST_SQL, Tenant: "cgrates.org", Account: "1001",
|
||||
ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}
|
||||
maa := APItoModelAccountAction(aa)
|
||||
if err := mysqlDb.SetTpAccountActions([]TpAccountAction{*maa}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := mysqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(aas) == 0 {
|
||||
t.Error("Could not create TPAccountActions")
|
||||
}
|
||||
// Remove AccountActions
|
||||
if err := mysqlDb.RemTpData(utils.TBL_TP_ACCOUNT_ACTIONS, aa.TPid, map[string]string{"loadid": aa.LoadId, "tenant": aa.Tenant, "account": aa.Account}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := mysqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aas) != 0 {
|
||||
t.Errorf("Non empty account actions: %+v", aas)
|
||||
}
|
||||
// Create again so we can test complete TP removal
|
||||
if err := mysqlDb.SetTpTimings([]TpTiming{*tms}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := mysqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(tmgs) == 0 {
|
||||
t.Error("Could not store TPTiming")
|
||||
}
|
||||
// Create RatingProfile
|
||||
if err := mysqlDb.SetTpRatingProfiles(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := mysqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rps) == 0 {
|
||||
t.Error("Could not store TPRatingProfile")
|
||||
}
|
||||
// Create AccountActions
|
||||
if err := mysqlDb.SetTpAccountActions([]TpAccountAction{*maa}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := mysqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(aas) == 0 {
|
||||
t.Error("Could not create TPAccountActions")
|
||||
}
|
||||
// Remove TariffPlan completely
|
||||
if err := mysqlDb.RemTpData("", utils.TEST_SQL, nil); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
// Make sure we have removed it
|
||||
if tms, err := mysqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(tms) != 0 {
|
||||
t.Errorf("Non empty timings: %+v", tms)
|
||||
}
|
||||
if rpfs, err := mysqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(rpfs) != 0 {
|
||||
t.Errorf("Non empty rpfs: %+v", rpfs)
|
||||
}
|
||||
if aas, err := mysqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aas) != 0 {
|
||||
t.Errorf("Non empty account actions: %+v", aas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
cgrCdr1 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa1", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:20Z",
|
||||
utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "10s", utils.PDD: "4s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", utils.CDRSOURCE: utils.TEST_SQL}
|
||||
|
||||
cgrCdr2 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa2", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_PREPAID, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:22Z",
|
||||
utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "20", utils.PDD: "7s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
cgrCdr3 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa3", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org",
|
||||
utils.CATEGORY: "premium_call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "1001", utils.SETUP_TIME: "2013-11-07T08:42:24Z",
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "60s", utils.PDD: "4s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
cgrCdr4 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa4", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_PSEUDOPREPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "+4986517174964", utils.SETUP_TIME: "2013-11-07T08:42:21Z",
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "1m2s", utils.PDD: "4s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
cgrCdr5 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa5", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_POSTPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "+4986517174963", utils.SETUP_TIME: "2013-11-07T08:42:25Z",
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "15s", utils.PDD: "7s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
for _, cdr := range []*CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} {
|
||||
if err := mysqlDb.SetCdr(cdr.AsStoredCdr("")); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
strCdr1 := &CDR{TOR: utils.VOICE, OriginID: "bbb1", OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr1.CGRID = utils.Sha1(strCdr1.OriginID, strCdr1.SetupTime.String())
|
||||
strCdr2 := &CDR{TOR: utils.VOICE, OriginID: "bbb2", OriginHost: "192.168.1.2", Source: "UNKNOWN2", RequestType: utils.META_PREPAID,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(12) * time.Second, PDD: time.Duration(4) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 0.201}
|
||||
strCdr2.CGRID = utils.Sha1(strCdr2.OriginID, strCdr2.SetupTime.String())
|
||||
strCdr3 := &CDR{TOR: utils.VOICE, OriginID: "bbb3", OriginHost: "192.168.1.1", Source: utils.TEST_SQL, RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1000", Destination: "+4986517174963",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(2) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr3.CGRID = utils.Sha1(strCdr3.OriginID, strCdr3.SetupTime.String())
|
||||
|
||||
for _, cdr := range []*CDR{strCdr1, strCdr2, strCdr3} {
|
||||
if err := mysqlDb.SetCdr(cdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLSetRatedCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
strCdr1 := &CDR{TOR: utils.VOICE, OriginID: "bbb1", OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr1.CGRID = utils.Sha1(strCdr1.OriginID, strCdr1.SetupTime.String())
|
||||
strCdr2 := &CDR{TOR: utils.VOICE, OriginID: "bbb2", OriginHost: "192.168.1.2", Source: "UNKNOWN", RequestType: utils.META_PREPAID,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(12) * time.Second, PDD: time.Duration(7) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 0.201}
|
||||
strCdr2.CGRID = utils.Sha1(strCdr2.OriginID, strCdr2.SetupTime.String())
|
||||
strCdr3 := &CDR{TOR: utils.VOICE, OriginID: "bbb3", OriginHost: "192.168.1.1", Source: utils.TEST_SQL, RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1002", Destination: "+4986517174964",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(2) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: "wholesale_run", Cost: 1.201}
|
||||
strCdr3.CGRID = utils.Sha1(strCdr3.OriginID, strCdr3.SetupTime.String())
|
||||
|
||||
for _, cdr := range []*CDR{strCdr1, strCdr2, strCdr3} {
|
||||
if err := mysqlDb.SetRatedCdr(cdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLCallCost(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
CGRID := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
cc := &CallCost{
|
||||
Direction: "*out",
|
||||
Category: "call",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "91001",
|
||||
Account: "8001",
|
||||
Destination: "1002",
|
||||
TOR: utils.VOICE,
|
||||
Timespans: []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 13, 40, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC),
|
||||
},
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 10, 13, 41, 30, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := mysqlDb.LogCallCost(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID, cc); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if ccRcv, err := mysqlDb.GetCallCostLog(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(cc, ccRcv) {
|
||||
t.Errorf("Expecting call cost: %v, received: %v", cc, ccRcv)
|
||||
}
|
||||
// UPDATE test here
|
||||
cc.Category = "premium_call"
|
||||
if err := mysqlDb.LogCallCost(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID, cc); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if ccRcv, err := mysqlDb.GetCallCostLog(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(cc, ccRcv) {
|
||||
t.Errorf("Expecting call cost: %v, received: %v", cc, ccRcv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLGetCDRs(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
var timeStart, timeEnd time.Time
|
||||
// All CDRs, no filter
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(new(utils.CDRsFilter)); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Count ALL
|
||||
if storedCdrs, count, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Count: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 0 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
} else if count != 8 {
|
||||
t.Error("Unexpected count of StoredCdrs returned: ", count)
|
||||
}
|
||||
// Limit 5
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Paginator: utils.Paginator{Limit: utils.IntPointer(5), Offset: utils.IntPointer(0)}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Offset 5
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Paginator: utils.Paginator{Limit: utils.IntPointer(5), Offset: utils.IntPointer(0)}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Offset with limit 2
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Paginator: utils.Paginator{Limit: utils.IntPointer(2), Offset: utils.IntPointer(5)}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", len(storedCdrs))
|
||||
}
|
||||
// Filter on CGRIDs
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Count on CGRIDS
|
||||
if _, count, err := mysqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, Count: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if count != 2 {
|
||||
t.Error("Unexpected count of StoredCdrs returned: ", count)
|
||||
}
|
||||
// Filter on CGRIDs plus RequestType
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, RequestTypes: []string{utils.META_PREPAID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Count on multiple filter
|
||||
if _, count, err := mysqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, RequestTypes: []string{utils.META_PREPAID}, Count: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if count != 1 {
|
||||
t.Error("Unexpected count of StoredCdrs returned: ", count)
|
||||
}
|
||||
// Filter on runId
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{RunIDs: []string{utils.DEFAULT_RUNID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on TOR
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{TORs: []string{utils.SMS}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 0 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple TOR
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{TORs: []string{utils.SMS, utils.VOICE}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on OriginHost
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{OriginHosts: []string{"192.168.1.2"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple OriginHost
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{OriginHosts: []string{"192.168.1.1", "192.168.1.2"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on Source
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Sources: []string{"UNKNOWN"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple Source
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Sources: []string{"UNKNOWN", "UNKNOWN2"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on RequestType
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{RequestTypes: []string{utils.META_PREPAID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple RequestType
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{RequestTypes: []string{utils.META_PREPAID, utils.META_PSEUDOPREPAID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on direction
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Directions: []string{"*out"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on tenant
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Tenants: []string{"itsyscom.com"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple tenants
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Tenants: []string{"itsyscom.com", "cgrates.org"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on category
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Categories: []string{"premium_call"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple categories
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Categories: []string{"premium_call", "call"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on account
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Accounts: []string{"1002"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple account
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Accounts: []string{"1001", "1002"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on subject
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Subjects: []string{"1000"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple subject
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{Subjects: []string{"1000", "1002"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on destPrefix
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{DestinationPrefixes: []string{"+498651"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple DestinationPrefixes
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{DestinationPrefixes: []string{"1001", "+498651"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 4 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on ignoreRated
|
||||
var OrderIDStart, OrderIDEnd int64 // Capture also orderIds for the next test
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{MaxCost: utils.Float64Pointer(0.0)}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
} else {
|
||||
for _, cdr := range storedCdrs {
|
||||
if cdr.OrderID < OrderIDStart {
|
||||
OrderIDStart = cdr.OrderID
|
||||
}
|
||||
if cdr.OrderID > OrderIDEnd {
|
||||
OrderIDEnd = cdr.OrderID
|
||||
}
|
||||
}
|
||||
}
|
||||
// Filter on OrderIDStart
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{OrderIDStart: OrderIDStart}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on OrderIDStart and OrderIDEnd
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{OrderIDStart: OrderIDStart, OrderIDEnd: OrderIDEnd}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 4 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on timeStart
|
||||
timeStart = time.Date(2013, 11, 8, 8, 0, 0, 0, time.UTC)
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{AnswerTimeStart: &timeStart}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on timeStart and timeEnd
|
||||
timeEnd = time.Date(2013, 12, 1, 8, 0, 0, 0, time.UTC)
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on minPDD
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{MinPDD: utils.Float64Pointer(3)}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 7 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", len(storedCdrs))
|
||||
}
|
||||
// Filter on maxPDD
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{MaxPDD: utils.Float64Pointer(3)}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", len(storedCdrs))
|
||||
}
|
||||
// Filter on minPDD, maxPDD
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{MinPDD: utils.Float64Pointer(3), MaxPDD: utils.Float64Pointer(5)}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", len(storedCdrs))
|
||||
}
|
||||
// Combined filter
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{RequestTypes: []string{utils.META_RATED}, AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on ignoreDerived
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd, FilterOnRated: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 0 { // ToDo: Recheck this value
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLRemCDRs(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
CGRIDB1 := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
if err := mysqlDb.RemCDRs([]string{CGRIDB1}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(new(utils.CDRsFilter)); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 7 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
tm, _ := utils.ParseTimeDetectLayout("2013-11-08T08:42:20Z", "")
|
||||
CGRIDA1 := utils.Sha1("aaa1", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-08T08:42:22Z", "")
|
||||
CGRIDA2 := utils.Sha1("aaa2", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:24Z", "")
|
||||
CGRIDA3 := utils.Sha1("aaa3", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:21Z", "")
|
||||
CGRIDA4 := utils.Sha1("aaa4", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:25Z", "")
|
||||
CGRIDA5 := utils.Sha1("aaa5", tm.String())
|
||||
CGRIDB2 := utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
CGRIDB3 := utils.Sha1("bbb3", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
if err := mysqlDb.RemCDRs([]string{CGRIDA1, CGRIDA2, CGRIDA3, CGRIDA4, CGRIDA5,
|
||||
CGRIDB2, CGRIDB3}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if storedCdrs, _, err := mysqlDb.GetCDRs(new(utils.CDRsFilter)); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 0 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that what we get is what we set
|
||||
func TestMySQLStoreRestoreCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
strCdr := &CDR{TOR: utils.VOICE, OriginID: "ccc1", OriginHost: "192.168.1.1", Source: "TEST_CDR", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr.CGRID = utils.Sha1(strCdr.OriginID, strCdr.SetupTime.String())
|
||||
if err := mysqlDb.SetCdr(strCdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if err := mysqlDb.SetRatedCdr(strCdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
// Check RawCdr
|
||||
if rcvCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{strCdr.CGRID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rcvCdrs) != 1 {
|
||||
t.Errorf("Unexpected cdrs returned: %+v", rcvCdrs)
|
||||
} else {
|
||||
rcvCdr := rcvCdrs[0]
|
||||
if strCdr.CGRID != rcvCdr.CGRID ||
|
||||
strCdr.TOR != rcvCdr.TOR ||
|
||||
strCdr.OriginID != rcvCdr.OriginID ||
|
||||
strCdr.OriginHost != rcvCdr.OriginHost ||
|
||||
strCdr.RequestType != rcvCdr.RequestType ||
|
||||
strCdr.Direction != rcvCdr.Direction ||
|
||||
strCdr.Tenant != rcvCdr.Tenant ||
|
||||
strCdr.Category != rcvCdr.Category ||
|
||||
strCdr.Account != rcvCdr.Account ||
|
||||
strCdr.Subject != rcvCdr.Subject ||
|
||||
strCdr.Destination != rcvCdr.Destination ||
|
||||
!strCdr.SetupTime.Equal(rcvCdr.SetupTime) ||
|
||||
!strCdr.AnswerTime.Equal(rcvCdr.AnswerTime) ||
|
||||
strCdr.Usage != rcvCdr.Usage ||
|
||||
strCdr.PDD != rcvCdr.PDD ||
|
||||
strCdr.Supplier != rcvCdr.Supplier ||
|
||||
strCdr.DisconnectCause != rcvCdr.DisconnectCause ||
|
||||
!reflect.DeepEqual(strCdr.ExtraFields, rcvCdr.ExtraFields) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", strCdr, rcvCdrs[0])
|
||||
}
|
||||
}
|
||||
// Check RatedCdr
|
||||
if rcvCdrs, _, err := mysqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{strCdr.CGRID}, FilterOnRated: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rcvCdrs) != 1 {
|
||||
t.Errorf("Unexpected cdrs returned: %+v", rcvCdrs)
|
||||
} else {
|
||||
rcvCdr := rcvCdrs[0]
|
||||
if strCdr.CGRID != rcvCdr.CGRID ||
|
||||
strCdr.TOR != rcvCdr.TOR ||
|
||||
strCdr.OriginID != rcvCdr.OriginID ||
|
||||
strCdr.OriginHost != rcvCdr.OriginHost ||
|
||||
strCdr.RequestType != rcvCdr.RequestType ||
|
||||
strCdr.Direction != rcvCdr.Direction ||
|
||||
strCdr.Tenant != rcvCdr.Tenant ||
|
||||
strCdr.Category != rcvCdr.Category ||
|
||||
strCdr.Account != rcvCdr.Account ||
|
||||
strCdr.Subject != rcvCdr.Subject ||
|
||||
strCdr.Destination != rcvCdr.Destination ||
|
||||
//!strCdr.SetupTime.Equal(rcvCdr.SetupTime) || // FixMe
|
||||
//!strCdr.AnswerTime.Equal(rcvCdr.AnswerTime) || // FixMe
|
||||
strCdr.Usage != rcvCdr.Usage ||
|
||||
strCdr.PDD != rcvCdr.PDD ||
|
||||
strCdr.Supplier != rcvCdr.Supplier ||
|
||||
strCdr.DisconnectCause != rcvCdr.DisconnectCause ||
|
||||
strCdr.Cost != rcvCdr.Cost ||
|
||||
!reflect.DeepEqual(strCdr.ExtraFields, rcvCdr.ExtraFields) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", strCdr, rcvCdrs[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,971 +0,0 @@
|
||||
/*
|
||||
Rating system designed to be used in VoIP Carriers World
|
||||
Copyright (C) 2012-2015 ITsysCOM
|
||||
|
||||
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 engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var psqlDb *PostgresStorage
|
||||
|
||||
func TestPSQLCreateTables(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
cgrConfig, _ := config.NewDefaultCGRConfig()
|
||||
var err error
|
||||
if psqlDb, err = NewPostgresStorage("localhost", "5432", cgrConfig.StorDBName, cgrConfig.StorDBUser, cgrConfig.StorDBPass,
|
||||
cgrConfig.StorDBMaxOpenConns, cgrConfig.StorDBMaxIdleConns); err != nil {
|
||||
t.Error("Error on opening database connection: ", err)
|
||||
return
|
||||
}
|
||||
for _, scriptName := range []string{utils.CREATE_CDRS_TABLES_SQL, utils.CREATE_TARIFFPLAN_TABLES_SQL} {
|
||||
if err := psqlDb.CreateTablesFromScript(path.Join(*dataDir, "storage", utils.POSTGRES, scriptName)); err != nil {
|
||||
t.Error("Error on psqlDb creation: ", err.Error())
|
||||
return // No point in going further
|
||||
}
|
||||
}
|
||||
if _, err := psqlDb.Db.Query(fmt.Sprintf("SELECT 1 from %s", utils.TBL_CDRS)); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPTiming(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
tm := &utils.ApierTPTiming{TPid: utils.TEST_SQL, TimingId: "ALWAYS", Time: "00:00:00"}
|
||||
mtm := APItoModelTiming(tm)
|
||||
mtms := []TpTiming{*mtm}
|
||||
if err := psqlDb.SetTpTimings(mtms); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := psqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mtms[0], tmgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mtms, tmgs)
|
||||
}
|
||||
// Update
|
||||
tm.Time = "00:00:01"
|
||||
if err := psqlDb.SetTpTimings(mtms); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := psqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mtms[0], tmgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mtms, tmgs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPDestination(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
dst := &utils.TPDestination{TPid: utils.TEST_SQL, DestinationId: utils.TEST_SQL, Prefixes: []string{"+49", "+49151", "+49176"}}
|
||||
dests := APItoModelDestination(dst)
|
||||
if err := psqlDb.SetTpDestinations(dests); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
storData, err := psqlDb.GetTpDestinations(utils.TEST_SQL, utils.TEST_SQL)
|
||||
dsts, err := TpDestinations(storData).GetDestinations()
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(dst.Prefixes) != len(dsts[utils.TEST_SQL].Prefixes) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", dst, dsts[utils.TEST_SQL])
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPRates(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
RT_ID := "RT_1"
|
||||
rtSlots := []*utils.RateSlot{
|
||||
&utils.RateSlot{ConnectFee: 0.02, Rate: 0.01, RateUnit: "60s", RateIncrement: "60s", GroupIntervalStart: "0s"},
|
||||
&utils.RateSlot{ConnectFee: 0.00, Rate: 0.005, RateUnit: "60s", RateIncrement: "1s", GroupIntervalStart: "60s"},
|
||||
}
|
||||
for _, rs := range rtSlots {
|
||||
rs.SetDurations()
|
||||
}
|
||||
expectedTPRate := &utils.TPRate{TPid: utils.TEST_SQL, RateId: RT_ID, RateSlots: rtSlots}
|
||||
mRates := APItoModelRate(expectedTPRate)
|
||||
if err := psqlDb.SetTpRates(mRates); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
rts, err := psqlDb.GetTpRates(utils.TEST_SQL, RT_ID)
|
||||
trts, err := TpRates(rts).GetRates()
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(expectedTPRate.RateSlots) != len(trts[RT_ID].RateSlots) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", expectedTPRate, trts[RT_ID])
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPDestinationRates(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
DR_ID := "DR_1"
|
||||
dr := &utils.DestinationRate{DestinationId: "DST_1", RateId: "RT_1", RoundingMethod: "*up", RoundingDecimals: 4}
|
||||
eDrs := &utils.TPDestinationRate{TPid: utils.TEST_SQL, DestinationRateId: DR_ID, DestinationRates: []*utils.DestinationRate{dr}}
|
||||
mdrs := APItoModelDestinationRate(eDrs)
|
||||
if err := psqlDb.SetTpDestinationRates(mdrs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if drs, err := psqlDb.GetTpDestinationRates(utils.TEST_SQL, DR_ID, nil); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mdrs[0], drs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mdrs, drs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPRatingPlans(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
RP_ID := "RP_1"
|
||||
rbBinding := &utils.TPRatingPlanBinding{DestinationRatesId: "DR_1", TimingId: "TM_1", Weight: 10.0}
|
||||
rp := &utils.TPRatingPlan{
|
||||
TPid: utils.TEST_SQL,
|
||||
RatingPlanId: RP_ID,
|
||||
RatingPlanBindings: []*utils.TPRatingPlanBinding{rbBinding},
|
||||
}
|
||||
mrp := APItoModelRatingPlan(rp)
|
||||
|
||||
if err := psqlDb.SetTpRatingPlans(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if drps, err := psqlDb.GetTpRatingPlans(utils.TEST_SQL, RP_ID, nil); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mrp[0], drps[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mrp, drps)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPRatingProfiles(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RP_1"}}
|
||||
rp := &utils.TPRatingProfile{TPid: utils.TEST_SQL, LoadId: utils.TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras}
|
||||
|
||||
mrp := APItoModelRatingProfile(rp)
|
||||
if err := psqlDb.SetTpRatingProfiles(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := psqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mrp[0], rps[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mrp, rps)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPSharedGroups(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
SG_ID := "SG_1"
|
||||
tpSgs := &utils.TPSharedGroups{
|
||||
TPid: utils.TEST_SQL,
|
||||
SharedGroupsId: SG_ID,
|
||||
SharedGroups: []*utils.TPSharedGroup{
|
||||
&utils.TPSharedGroup{Account: "dan", Strategy: "*lowest_first", RatingSubject: "lowest_rates"},
|
||||
},
|
||||
}
|
||||
mSgs := APItoModelSharedGroup(tpSgs)
|
||||
if err := psqlDb.SetTpSharedGroups(mSgs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if sgs, err := psqlDb.GetTpSharedGroups(utils.TEST_SQL, SG_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mSgs[0], sgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mSgs, sgs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPCdrStats(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
CS_ID := "CDRSTATS_1"
|
||||
setCS := &utils.TPCdrStats{
|
||||
TPid: utils.TEST_SQL,
|
||||
CdrStatsId: CS_ID,
|
||||
CdrStats: []*utils.TPCdrStat{
|
||||
&utils.TPCdrStat{QueueLength: "10", TimeWindow: "10m", Metrics: "ASR", Tenants: "cgrates.org", Categories: "call"},
|
||||
},
|
||||
}
|
||||
mcs := APItoModelCdrStat(setCS)
|
||||
if err := psqlDb.SetTpCdrStats(mcs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if cs, err := psqlDb.GetTpCdrStats(utils.TEST_SQL, CS_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mcs[0], cs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mcs, cs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPDerivedChargers(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
dc := &utils.TPDerivedCharger{RunId: utils.DEFAULT_RUNID, ReqTypeField: "^" + utils.META_PREPAID, AccountField: "^rif", SubjectField: "^rif",
|
||||
UsageField: "cgr_duration", SupplierField: "^supplier1"}
|
||||
dcs := &utils.TPDerivedChargers{TPid: utils.TEST_SQL, Direction: utils.OUT, Tenant: "cgrates.org", Category: "call", Account: "dan", Subject: "dan", DerivedChargers: []*utils.TPDerivedCharger{dc}}
|
||||
mdcs := APItoModelDerivedCharger(dcs)
|
||||
if err := psqlDb.SetTpDerivedChargers(mdcs); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rDCs, err := psqlDb.GetTpDerivedChargers(&mdcs[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mdcs[0], rDCs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mdcs, rDCs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPActions(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
ACTS_ID := "PREPAID_10"
|
||||
acts := []*utils.TPAction{
|
||||
&utils.TPAction{Identifier: "*topup_reset", BalanceType: "*monetary", Directions: "*out", Units: 10, ExpiryTime: "*unlimited",
|
||||
DestinationIds: "*any", BalanceWeight: 10, Weight: 10}}
|
||||
tpActions := &utils.TPActions{TPid: utils.TEST_SQL, ActionsId: ACTS_ID, Actions: acts}
|
||||
mas := APItoModelAction(tpActions)
|
||||
if err := psqlDb.SetTpActions(mas); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rTpActs, err := psqlDb.GetTpActions(utils.TEST_SQL, ACTS_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(mas[0], rTpActs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", mas, rTpActs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLTPActionTimings(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
AP_ID := "AP_1"
|
||||
ap := &utils.TPActionPlan{
|
||||
TPid: utils.TEST_SQL,
|
||||
ActionPlanId: AP_ID,
|
||||
ActionPlan: []*utils.TPActionTiming{&utils.TPActionTiming{ActionsId: "ACTS_1", TimingId: "TM_1", Weight: 10.0}},
|
||||
}
|
||||
maps := APItoModelActionPlan(ap)
|
||||
if err := psqlDb.SetTpActionPlans(maps); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rAP, err := psqlDb.GetTpActionPlans(utils.TEST_SQL, AP_ID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(maps[0], rAP[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", maps, rAP)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTPActionTriggers(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
atrg := &utils.TPActionTrigger{
|
||||
Id: "MY_FIRST_ATGR",
|
||||
BalanceType: "*monetary",
|
||||
BalanceDirections: "*out",
|
||||
ThresholdType: "*min_balance",
|
||||
ThresholdValue: 2.0,
|
||||
Recurrent: true,
|
||||
BalanceDestinationIds: "*any",
|
||||
Weight: 10.0,
|
||||
ActionsId: "LOG_BALANCE",
|
||||
}
|
||||
atrgs := &utils.TPActionTriggers{
|
||||
TPid: utils.TEST_SQL,
|
||||
ActionTriggersId: utils.TEST_SQL,
|
||||
ActionTriggers: []*utils.TPActionTrigger{atrg},
|
||||
}
|
||||
matrg := APItoModelActionTrigger(atrgs)
|
||||
if err := psqlDb.SetTpActionTriggers(matrg); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
}
|
||||
if rcvMpAtrgs, err := psqlDb.GetTpActionTriggers(utils.TEST_SQL, utils.TEST_SQL); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
} else if !modelEqual(matrg[0], rcvMpAtrgs[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", matrg, rcvMpAtrgs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetGetTpAccountActions(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
aa := &utils.TPAccountActions{TPid: utils.TEST_SQL, Tenant: "cgrates.org", Account: "1001",
|
||||
ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}
|
||||
maa := APItoModelAccountAction(aa)
|
||||
if err := psqlDb.SetTpAccountActions([]TpAccountAction{*maa}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := psqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !modelEqual(*maa, aas[0]) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", maa, aas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLGetTPIds(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
eTPIds := []string{utils.TEST_SQL}
|
||||
if tpIds, err := psqlDb.GetTpIds(); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(eTPIds, tpIds) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eTPIds, tpIds)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLRemoveTPData(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
// Create Timings
|
||||
tm := &utils.ApierTPTiming{TPid: utils.TEST_SQL, TimingId: "ALWAYS", Time: "00:00:00"}
|
||||
tms := APItoModelTiming(tm)
|
||||
if err := psqlDb.SetTpTimings([]TpTiming{*tms}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := psqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(tmgs) == 0 {
|
||||
t.Error("Could not store TPTiming")
|
||||
}
|
||||
// Remove Timings
|
||||
if err := psqlDb.RemTpData(utils.TBL_TP_TIMINGS, utils.TEST_SQL, map[string]string{"tag": tm.TimingId}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := psqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(tmgs) != 0 {
|
||||
t.Errorf("Timings should be empty, got instead: %+v", tmgs)
|
||||
}
|
||||
// Create RatingProfile
|
||||
ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RETAIL1"}}
|
||||
rp := &utils.TPRatingProfile{TPid: utils.TEST_SQL, LoadId: utils.TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras}
|
||||
mrp := APItoModelRatingProfile(rp)
|
||||
if err := psqlDb.SetTpRatingProfiles(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := psqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rps) == 0 {
|
||||
t.Error("Could not store TPRatingProfile")
|
||||
}
|
||||
// Remove RatingProfile
|
||||
if err := psqlDb.RemTpData(utils.TBL_TP_RATE_PROFILES, rp.TPid, map[string]string{"loadid": rp.LoadId, "direction": rp.Direction, "tenant": rp.Tenant, "category": rp.Category, "subject": rp.Subject}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := psqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(rps) != 0 {
|
||||
t.Errorf("RatingProfiles different than 0: %+v", rps)
|
||||
}
|
||||
// Create AccountActions
|
||||
aa := &utils.TPAccountActions{TPid: utils.TEST_SQL, LoadId: utils.TEST_SQL, Tenant: "cgrates.org", Account: "1001",
|
||||
ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"}
|
||||
maa := APItoModelAccountAction(aa)
|
||||
if err := psqlDb.SetTpAccountActions([]TpAccountAction{*maa}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := psqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(aas) == 0 {
|
||||
t.Error("Could not create TPAccountActions")
|
||||
}
|
||||
// Remove AccountActions
|
||||
if err := psqlDb.RemTpData(utils.TBL_TP_ACCOUNT_ACTIONS, aa.TPid, map[string]string{"loadid": aa.LoadId, "tenant": aa.Tenant, "account": aa.Account}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := psqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aas) != 0 {
|
||||
t.Errorf("Non empty account actions: %+v", aas)
|
||||
}
|
||||
// Create again so we can test complete TP removal
|
||||
if err := psqlDb.SetTpTimings([]TpTiming{*tms}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if tmgs, err := psqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(tmgs) == 0 {
|
||||
t.Error("Could not store TPTiming")
|
||||
}
|
||||
// Create RatingProfile
|
||||
if err := psqlDb.SetTpRatingProfiles(mrp); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if rps, err := psqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rps) == 0 {
|
||||
t.Error("Could not store TPRatingProfile")
|
||||
}
|
||||
// Create AccountActions
|
||||
if err := psqlDb.SetTpAccountActions([]TpAccountAction{*maa}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if aas, err := psqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(aas) == 0 {
|
||||
t.Error("Could not create TPAccountActions")
|
||||
}
|
||||
// Remove TariffPlan completely
|
||||
if err := psqlDb.RemTpData("", utils.TEST_SQL, nil); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
// Make sure we have removed it
|
||||
if tms, err := psqlDb.GetTpTimings(utils.TEST_SQL, tm.TimingId); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(tms) != 0 {
|
||||
t.Errorf("Non empty timings: %+v", tms)
|
||||
}
|
||||
if rpfs, err := psqlDb.GetTpRatingProfiles(&mrp[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(rpfs) != 0 {
|
||||
t.Errorf("Non empty rpfs: %+v", rpfs)
|
||||
}
|
||||
if aas, err := psqlDb.GetTpAccountActions(maa); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(aas) != 0 {
|
||||
t.Errorf("Non empty account actions: %+v", aas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
cgrCdr1 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa1", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:20Z",
|
||||
utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "10s", utils.PDD: "4s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", utils.CDRSOURCE: utils.TEST_SQL}
|
||||
|
||||
cgrCdr2 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa2", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_PREPAID, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:22Z",
|
||||
utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "20", utils.PDD: "7s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
cgrCdr3 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa3", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: utils.META_RATED, utils.DIRECTION: "*out", utils.TENANT: "cgrates.org",
|
||||
utils.CATEGORY: "premium_call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "1001", utils.SETUP_TIME: "2013-11-07T08:42:24Z",
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "60s", utils.PDD: "4s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
cgrCdr4 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa4", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_PSEUDOPREPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "+4986517174964", utils.SETUP_TIME: "2013-11-07T08:42:21Z",
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "1m2s", utils.PDD: "4s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
cgrCdr5 := &CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa5", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: utils.META_POSTPAID, utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com",
|
||||
utils.CATEGORY: "call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "+4986517174963", utils.SETUP_TIME: "2013-11-07T08:42:25Z",
|
||||
utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "15s", utils.PDD: "7s", utils.SUPPLIER: "SUPPL1", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": utils.TEST_SQL}
|
||||
|
||||
for _, cdr := range []*CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} {
|
||||
if err := psqlDb.SetCdr(cdr.AsStoredCdr("")); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
strCdr1 := &CDR{TOR: utils.VOICE, OriginID: "bbb1", OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr1.CGRID = utils.Sha1(strCdr1.OriginID, strCdr1.SetupTime.String())
|
||||
strCdr2 := &CDR{TOR: utils.VOICE, OriginID: "bbb2", OriginHost: "192.168.1.2", Source: "UNKNOWN2", RequestType: utils.META_PREPAID,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(12) * time.Second, PDD: time.Duration(4) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 0.201}
|
||||
strCdr2.CGRID = utils.Sha1(strCdr2.OriginID, strCdr2.SetupTime.String())
|
||||
strCdr3 := &CDR{TOR: utils.VOICE, OriginID: "bbb3", OriginHost: "192.168.1.1", Source: utils.TEST_SQL, RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1000", Destination: "+4986517174963",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(2) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr3.CGRID = utils.Sha1(strCdr3.OriginID, strCdr3.SetupTime.String())
|
||||
|
||||
for _, cdr := range []*CDR{strCdr1, strCdr2, strCdr3} {
|
||||
if err := psqlDb.SetCdr(cdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLCallCost(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
CGRID := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
cc := &CallCost{
|
||||
Direction: "*out",
|
||||
Category: "call",
|
||||
Tenant: "cgrates.org",
|
||||
Subject: "91001",
|
||||
Account: "8001",
|
||||
Destination: "1002",
|
||||
TOR: utils.VOICE,
|
||||
Timespans: []*TimeSpan{
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 13, 40, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC),
|
||||
},
|
||||
&TimeSpan{
|
||||
TimeStart: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC),
|
||||
TimeEnd: time.Date(2013, 9, 10, 13, 41, 30, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := psqlDb.LogCallCost(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID, cc); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if ccRcv, err := psqlDb.GetCallCostLog(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(cc, ccRcv) {
|
||||
t.Errorf("Expecting call cost: %v, received: %v", cc, ccRcv)
|
||||
}
|
||||
// UPDATE test here
|
||||
cc.Category = "premium_call"
|
||||
if err := psqlDb.LogCallCost(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID, cc); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if ccRcv, err := psqlDb.GetCallCostLog(CGRID, utils.TEST_SQL, utils.DEFAULT_RUNID); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(cc, ccRcv) {
|
||||
t.Errorf("Expecting call cost: %v, received: %v", cc, ccRcv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLSetRatedCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
strCdr1 := &CDR{TOR: utils.VOICE, OriginID: "bbb1", OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr1.CGRID = utils.Sha1(strCdr1.OriginID, strCdr1.SetupTime.String())
|
||||
strCdr2 := &CDR{TOR: utils.VOICE, OriginID: "bbb2", OriginHost: "192.168.1.2", Source: "UNKNOWN", RequestType: utils.META_PREPAID,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(12) * time.Second, PDD: time.Duration(7) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 0.201}
|
||||
strCdr2.CGRID = utils.Sha1(strCdr2.OriginID, strCdr2.SetupTime.String())
|
||||
strCdr3 := &CDR{TOR: utils.VOICE, OriginID: "bbb3", OriginHost: "192.168.1.1", Source: utils.TEST_SQL, RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1002", Destination: "+4986517174964",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(2) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: "wholesale_run", Cost: 1.201}
|
||||
strCdr3.CGRID = utils.Sha1(strCdr3.OriginID, strCdr3.SetupTime.String())
|
||||
|
||||
for _, cdr := range []*CDR{strCdr1, strCdr2, strCdr3} {
|
||||
if err := psqlDb.SetRatedCdr(cdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLGetCDRs(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
var timeStart, timeEnd time.Time
|
||||
// All CDRs, no filter
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(new(utils.CDRsFilter)); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Count ALL
|
||||
if storedCdrs, count, err := psqlDb.GetCDRs(&utils.CDRsFilter{Count: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 0 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
} else if count != 8 {
|
||||
t.Error("Unexpected count of StoredCdrs returned: ", count)
|
||||
}
|
||||
// Limit 5
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Paginator: utils.Paginator{Limit: utils.IntPointer(5), Offset: utils.IntPointer(0)}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Offset 5
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Paginator: utils.Paginator{Limit: utils.IntPointer(5), Offset: utils.IntPointer(0)}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Offset with limit 2
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Paginator: utils.Paginator{Limit: utils.IntPointer(2), Offset: utils.IntPointer(5)}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", len(storedCdrs))
|
||||
}
|
||||
// Filter on CGRIDs
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Count on CGRIDS
|
||||
if _, count, err := psqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, Count: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if count != 2 {
|
||||
t.Error("Unexpected count of StoredCdrs returned: ", count)
|
||||
}
|
||||
// Filter on CGRIDs plus RequestType
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, RequestTypes: []string{utils.META_PREPAID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Count on multiple filter
|
||||
if _, count, err := psqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, RequestTypes: []string{utils.META_PREPAID}, Count: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if count != 1 {
|
||||
t.Error("Unexpected count of StoredCdrs returned: ", count)
|
||||
}
|
||||
// Filter on runId
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{RunIDs: []string{utils.DEFAULT_RUNID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on TOR
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{TORs: []string{utils.SMS}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 0 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple TOR
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{TORs: []string{utils.SMS, utils.VOICE}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on OriginHost
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{OriginHosts: []string{"192.168.1.2"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple OriginHost
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{OriginHosts: []string{"192.168.1.1", "192.168.1.2"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on Source
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Sources: []string{"UNKNOWN"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple Source
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Sources: []string{"UNKNOWN", "UNKNOWN2"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on RequestType
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{RequestTypes: []string{utils.META_PREPAID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple RequestType
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{RequestTypes: []string{utils.META_PREPAID, utils.META_PSEUDOPREPAID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on direction
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Directions: []string{"*out"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on tenant
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Tenants: []string{"itsyscom.com"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple tenants
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Tenants: []string{"itsyscom.com", "cgrates.org"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on category
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Categories: []string{"premium_call"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple categories
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Categories: []string{"premium_call", "call"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on account
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Accounts: []string{"1002"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple account
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Accounts: []string{"1001", "1002"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on subject
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Subjects: []string{"1000"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple subject
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{Subjects: []string{"1000", "1002"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on destPrefix
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{DestinationPrefixes: []string{"+498651"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 3 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on multiple DestinationPrefixes
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{DestinationPrefixes: []string{"1001", "+498651"}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 4 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on ignoreRated
|
||||
var OrderIDStart, OrderIDEnd int64 // Capture also orderIds for the next test
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{MaxCost: utils.Float64Pointer(0.0)}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
} else {
|
||||
for _, cdr := range storedCdrs {
|
||||
if cdr.OrderID < OrderIDStart {
|
||||
OrderIDStart = cdr.OrderID
|
||||
}
|
||||
if cdr.OrderID > OrderIDEnd {
|
||||
OrderIDEnd = cdr.OrderID
|
||||
}
|
||||
}
|
||||
}
|
||||
// Filter on OrderIDStart
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{OrderIDStart: OrderIDStart}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 8 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on OrderIDStart and OrderIDEnd
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{OrderIDStart: OrderIDStart, OrderIDEnd: OrderIDEnd}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 4 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on timeStart
|
||||
timeStart = time.Date(2013, 11, 8, 8, 0, 0, 0, time.UTC)
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{AnswerTimeStart: &timeStart}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on timeStart and timeEnd
|
||||
timeEnd = time.Date(2013, 12, 1, 8, 0, 0, 0, time.UTC)
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 2 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on minPDD
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{MinPDD: utils.Float64Pointer(3)}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 7 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on maxPDD
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{MaxPDD: utils.Float64Pointer(3)}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on minPDD, maxPDD
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{MinPDD: utils.Float64Pointer(3), MaxPDD: utils.Float64Pointer(5)}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 5 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Combined filter
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{RequestTypes: []string{utils.META_RATED}, AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 1 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
// Filter on ignoreDerived
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd, FilterOnRated: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 0 { // ToDo: Recheck this value
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPSQLRemCDRs(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
CGRIDB1 := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
if err := psqlDb.RemCDRs([]string{CGRIDB1}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(new(utils.CDRsFilter)); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 7 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
tm, _ := utils.ParseTimeDetectLayout("2013-11-08T08:42:20Z", "")
|
||||
CGRIDA1 := utils.Sha1("aaa1", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-08T08:42:22Z", "")
|
||||
CGRIDA2 := utils.Sha1("aaa2", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:24Z", "")
|
||||
CGRIDA3 := utils.Sha1("aaa3", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:21Z", "")
|
||||
CGRIDA4 := utils.Sha1("aaa4", tm.String())
|
||||
tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:25Z", "")
|
||||
CGRIDA5 := utils.Sha1("aaa5", tm.String())
|
||||
CGRIDB2 := utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
CGRIDB3 := utils.Sha1("bbb3", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
|
||||
if err := psqlDb.RemCDRs([]string{CGRIDA1, CGRIDA2, CGRIDA3, CGRIDA4, CGRIDA5,
|
||||
CGRIDB2, CGRIDB3}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if storedCdrs, _, err := psqlDb.GetCDRs(new(utils.CDRsFilter)); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(storedCdrs) != 0 {
|
||||
t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that what we get is what we set
|
||||
func TestPSQLStoreRestoreCdr(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
strCdr := &CDR{TOR: utils.VOICE, OriginID: "ccc1", OriginHost: "192.168.1.1", Source: "TEST_CDR", RequestType: utils.META_RATED,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
Usage: time.Duration(10) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "SUPPL1",
|
||||
ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
|
||||
RunID: utils.DEFAULT_RUNID, Cost: 1.201}
|
||||
strCdr.CGRID = utils.Sha1(strCdr.OriginID, strCdr.SetupTime.String())
|
||||
if err := psqlDb.SetCdr(strCdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
if err := psqlDb.SetRatedCdr(strCdr); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
// Check RawCdr
|
||||
if rcvCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{strCdr.CGRID}}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rcvCdrs) != 1 {
|
||||
t.Errorf("Unexpected cdrs returned: %+v", rcvCdrs)
|
||||
} else {
|
||||
rcvCdr := rcvCdrs[0]
|
||||
if strCdr.CGRID != rcvCdr.CGRID ||
|
||||
strCdr.TOR != rcvCdr.TOR ||
|
||||
strCdr.OriginID != rcvCdr.OriginID ||
|
||||
strCdr.OriginHost != rcvCdr.OriginHost ||
|
||||
strCdr.RequestType != rcvCdr.RequestType ||
|
||||
strCdr.Direction != rcvCdr.Direction ||
|
||||
strCdr.Tenant != rcvCdr.Tenant ||
|
||||
strCdr.Category != rcvCdr.Category ||
|
||||
strCdr.Account != rcvCdr.Account ||
|
||||
strCdr.Subject != rcvCdr.Subject ||
|
||||
strCdr.Destination != rcvCdr.Destination ||
|
||||
!strCdr.SetupTime.Equal(rcvCdr.SetupTime) ||
|
||||
!strCdr.AnswerTime.Equal(rcvCdr.AnswerTime) ||
|
||||
strCdr.Usage != rcvCdr.Usage ||
|
||||
strCdr.PDD != rcvCdr.PDD ||
|
||||
strCdr.Supplier != rcvCdr.Supplier ||
|
||||
strCdr.DisconnectCause != rcvCdr.DisconnectCause ||
|
||||
!reflect.DeepEqual(strCdr.ExtraFields, rcvCdr.ExtraFields) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", strCdr, rcvCdrs[0])
|
||||
}
|
||||
}
|
||||
// Check RatedCdr
|
||||
if rcvCdrs, _, err := psqlDb.GetCDRs(&utils.CDRsFilter{CGRIDs: []string{strCdr.CGRID}, FilterOnRated: true}); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if len(rcvCdrs) != 1 {
|
||||
t.Errorf("Unexpected cdrs returned: %+v", rcvCdrs)
|
||||
} else {
|
||||
rcvCdr := rcvCdrs[0]
|
||||
if strCdr.CGRID != rcvCdr.CGRID ||
|
||||
strCdr.TOR != rcvCdr.TOR ||
|
||||
strCdr.OriginID != rcvCdr.OriginID ||
|
||||
strCdr.OriginHost != rcvCdr.OriginHost ||
|
||||
strCdr.RequestType != rcvCdr.RequestType ||
|
||||
strCdr.Direction != rcvCdr.Direction ||
|
||||
strCdr.Tenant != rcvCdr.Tenant ||
|
||||
strCdr.Category != rcvCdr.Category ||
|
||||
strCdr.Account != rcvCdr.Account ||
|
||||
strCdr.Subject != rcvCdr.Subject ||
|
||||
strCdr.Destination != rcvCdr.Destination ||
|
||||
//!strCdr.SetupTime.Equal(rcvCdr.SetupTime) || // FixMe
|
||||
//!strCdr.AnswerTime.Equal(rcvCdr.AnswerTime) || // FixMe
|
||||
strCdr.Usage != rcvCdr.Usage ||
|
||||
strCdr.PDD != rcvCdr.PDD ||
|
||||
strCdr.Supplier != rcvCdr.Supplier ||
|
||||
strCdr.DisconnectCause != rcvCdr.DisconnectCause ||
|
||||
strCdr.Cost != rcvCdr.Cost ||
|
||||
!reflect.DeepEqual(strCdr.ExtraFields, rcvCdr.ExtraFields) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", strCdr, rcvCdrs[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -590,7 +590,7 @@ func (self *SQLStorage) LogCallCost(cgrid, source, runid string, cc *CallCost) (
|
||||
Subject: cc.Subject,
|
||||
Destination: cc.Destination,
|
||||
Cost: cc.Cost,
|
||||
Timespans: string(tss),
|
||||
CostDetails: string(tss),
|
||||
CostSource: source,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
@@ -599,7 +599,7 @@ func (self *SQLStorage) LogCallCost(cgrid, source, runid string, cc *CallCost) (
|
||||
tx.Rollback()
|
||||
tx = self.db.Begin()
|
||||
updated := tx.Model(TBLCDRs{}).Where(&TBLCDRs{Cgrid: cgrid, RunID: runid}).Updates(&TBLCDRs{Tor: cc.TOR, Direction: cc.Direction, Tenant: cc.Tenant, Category: cc.Category,
|
||||
Account: cc.Account, Subject: cc.Subject, Destination: cc.Destination, Cost: cc.Cost, Timespans: string(tss), CostSource: source, UpdatedAt: time.Now()})
|
||||
Account: cc.Account, Subject: cc.Subject, Destination: cc.Destination, Cost: cc.Cost, CostDetails: string(tss), CostSource: source, UpdatedAt: time.Now()})
|
||||
if updated.Error != nil {
|
||||
tx.Rollback()
|
||||
return updated.Error
|
||||
@@ -614,7 +614,7 @@ func (self *SQLStorage) GetCallCostLog(cgrid, source, runid string) (*CallCost,
|
||||
if err := self.db.Where(&TBLCDRs{Cgrid: cgrid, RunID: runid, CostSource: source}).First(&tpCostDetail).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(tpCostDetail.Timespans) == 0 {
|
||||
if len(tpCostDetail.CostDetails) == 0 {
|
||||
return nil, nil // No costs returned
|
||||
}
|
||||
cc := new(CallCost)
|
||||
@@ -626,7 +626,7 @@ func (self *SQLStorage) GetCallCostLog(cgrid, source, runid string) (*CallCost,
|
||||
cc.Subject = tpCostDetail.Subject
|
||||
cc.Destination = tpCostDetail.Destination
|
||||
cc.Cost = tpCostDetail.Cost
|
||||
if err := json.Unmarshal([]byte(tpCostDetail.Timespans), &cc.Timespans); err != nil {
|
||||
if err := json.Unmarshal([]byte(tpCostDetail.CostDetails), &cc.Timespans); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cc, nil
|
||||
@@ -639,7 +639,7 @@ func (self *SQLStorage) LogActionPlan(source string, at *ActionPlan, as Actions)
|
||||
return
|
||||
}
|
||||
|
||||
func (self *SQLStorage) SetCdr(cdr *CDR) error {
|
||||
func (self *SQLStorage) SetCDR(cdr *CDR, allowUpdate bool) error {
|
||||
extraFields, err := json.Marshal(cdr.ExtraFields)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -647,10 +647,11 @@ func (self *SQLStorage) SetCdr(cdr *CDR) error {
|
||||
tx := self.db.Begin()
|
||||
saved := tx.Save(&TBLCDRs{
|
||||
Cgrid: cdr.CGRID,
|
||||
Tor: cdr.TOR,
|
||||
OriginID: cdr.OriginID,
|
||||
RunID: cdr.RunID,
|
||||
OriginHost: cdr.OriginHost,
|
||||
Source: cdr.Source,
|
||||
OriginID: cdr.OriginID,
|
||||
Tor: cdr.TOR,
|
||||
RequestType: cdr.RequestType,
|
||||
Direction: cdr.Direction,
|
||||
Tenant: cdr.Tenant,
|
||||
@@ -659,51 +660,51 @@ func (self *SQLStorage) SetCdr(cdr *CDR) error {
|
||||
Subject: cdr.Subject,
|
||||
Destination: cdr.Destination,
|
||||
SetupTime: cdr.SetupTime,
|
||||
Pdd: cdr.PDD.Seconds(),
|
||||
AnswerTime: cdr.AnswerTime,
|
||||
Usage: cdr.Usage.Seconds(),
|
||||
Pdd: cdr.PDD.Seconds(),
|
||||
Supplier: cdr.Supplier,
|
||||
DisconnectCause: cdr.DisconnectCause,
|
||||
ExtraFields: string(extraFields),
|
||||
CreatedAt: time.Now()})
|
||||
if saved.Error != nil {
|
||||
tx.Rollback()
|
||||
return saved.Error
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) SetRatedCdr(cdr *CDR) (err error) {
|
||||
tx := self.db.Begin()
|
||||
saved := tx.Save(&TBLCDRs{
|
||||
Cgrid: cdr.CGRID,
|
||||
RunID: cdr.RunID,
|
||||
RequestType: cdr.RequestType,
|
||||
Direction: cdr.Direction,
|
||||
Tenant: cdr.Tenant,
|
||||
Category: cdr.Category,
|
||||
Account: cdr.Account,
|
||||
Subject: cdr.Subject,
|
||||
Destination: cdr.Destination,
|
||||
SetupTime: cdr.SetupTime,
|
||||
AnswerTime: cdr.AnswerTime,
|
||||
Usage: cdr.Usage.Seconds(),
|
||||
Pdd: cdr.PDD.Seconds(),
|
||||
Supplier: cdr.Supplier,
|
||||
DisconnectCause: cdr.DisconnectCause,
|
||||
CostSource: cdr.CostSource,
|
||||
Cost: cdr.Cost,
|
||||
CostDetails: cdr.CostDetailsJson(),
|
||||
ExtraInfo: cdr.ExtraInfo,
|
||||
CreatedAt: time.Now(),
|
||||
})
|
||||
if saved.Error != nil {
|
||||
tx.Rollback()
|
||||
if !allowUpdate {
|
||||
return saved.Error
|
||||
}
|
||||
tx = self.db.Begin()
|
||||
updated := tx.Model(TBLCDRs{}).Where(&TBLCDRs{Cgrid: cdr.CGRID, RunID: cdr.RunID}).Updates(&TBLCDRs{RequestType: cdr.RequestType,
|
||||
Direction: cdr.Direction, Tenant: cdr.Tenant, Category: cdr.Category, Account: cdr.Account, Subject: cdr.Subject, Destination: cdr.Destination,
|
||||
SetupTime: cdr.SetupTime, AnswerTime: cdr.AnswerTime, Usage: cdr.Usage.Seconds(), Pdd: cdr.PDD.Seconds(), Supplier: cdr.Supplier, DisconnectCause: cdr.DisconnectCause,
|
||||
Cost: cdr.Cost, ExtraInfo: cdr.ExtraInfo,
|
||||
UpdatedAt: time.Now()})
|
||||
updated := tx.Model(TBLCDRs{}).Where(&TBLCDRs{Cgrid: cdr.CGRID, RunID: cdr.RunID}).Updates(
|
||||
&TBLCDRs{
|
||||
OriginHost: cdr.OriginHost,
|
||||
Source: cdr.Source,
|
||||
OriginID: cdr.OriginID,
|
||||
Tor: cdr.TOR,
|
||||
RequestType: cdr.RequestType,
|
||||
Direction: cdr.Direction,
|
||||
Tenant: cdr.Tenant,
|
||||
Category: cdr.Category,
|
||||
Account: cdr.Account,
|
||||
Subject: cdr.Subject,
|
||||
Destination: cdr.Destination,
|
||||
SetupTime: cdr.SetupTime,
|
||||
Pdd: cdr.PDD.Seconds(),
|
||||
AnswerTime: cdr.AnswerTime,
|
||||
Usage: cdr.Usage.Seconds(),
|
||||
Supplier: cdr.Supplier,
|
||||
DisconnectCause: cdr.DisconnectCause,
|
||||
ExtraFields: string(extraFields),
|
||||
CostSource: cdr.CostSource,
|
||||
Cost: cdr.Cost,
|
||||
CostDetails: cdr.CostDetailsJson(),
|
||||
ExtraInfo: cdr.ExtraInfo,
|
||||
UpdatedAt: time.Now(),
|
||||
},
|
||||
)
|
||||
if updated.Error != nil {
|
||||
tx.Rollback()
|
||||
return updated.Error
|
||||
@@ -711,7 +712,6 @@ func (self *SQLStorage) SetRatedCdr(cdr *CDR) (err error) {
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetCDRs(qryFltr *utils.CDRsFilter) ([]*CDR, int64, error) {
|
||||
@@ -937,14 +937,12 @@ func (self *SQLStorage) GetCDRs(qryFltr *utils.CDRsFilter) ([]*CDR, int64, error
|
||||
|
||||
for _, result := range results {
|
||||
var extraFieldsMp map[string]string
|
||||
var ccTimespans TimeSpans
|
||||
if len(result.ExtraFields) != 0 {
|
||||
if err := json.Unmarshal([]byte(result.ExtraFields), &extraFieldsMp); err != nil {
|
||||
return nil, 0, fmt.Errorf("JSON unmarshal error for cgrid: %s, runid: %v, error: %s", result.Cgrid, result.RunID, err.Error())
|
||||
}
|
||||
if err := json.Unmarshal([]byte(result.ExtraFields), &extraFieldsMp); err != nil {
|
||||
return nil, 0, fmt.Errorf("JSON unmarshal error for cgrid: %s, runid: %v, error: %s", result.Cgrid, result.RunID, err.Error())
|
||||
}
|
||||
if len(result.Timespans) != 0 {
|
||||
if err := json.Unmarshal([]byte(result.Timespans), &ccTimespans); err != nil {
|
||||
var callCost CallCost
|
||||
if len(result.CostDetails) != 0 {
|
||||
if err := json.Unmarshal([]byte(result.CostDetails), &callCost); err != nil {
|
||||
return nil, 0, fmt.Errorf("JSON unmarshal callcost error for cgrid: %s, runid: %v, error: %s", result.Cgrid, result.RunID, err.Error())
|
||||
}
|
||||
}
|
||||
@@ -952,11 +950,12 @@ func (self *SQLStorage) GetCDRs(qryFltr *utils.CDRsFilter) ([]*CDR, int64, error
|
||||
pddDur, _ := time.ParseDuration(strconv.FormatFloat(result.Pdd, 'f', -1, 64) + "s")
|
||||
storCdr := &CDR{
|
||||
CGRID: result.Cgrid,
|
||||
RunID: result.RunID,
|
||||
OrderID: result.ID,
|
||||
TOR: result.Tor,
|
||||
OriginID: result.OriginID,
|
||||
OriginHost: result.OriginHost,
|
||||
Source: result.Source,
|
||||
OriginID: result.OriginID,
|
||||
TOR: result.Tor,
|
||||
RequestType: result.RequestType,
|
||||
Direction: result.Direction,
|
||||
Tenant: result.Tenant,
|
||||
@@ -971,26 +970,11 @@ func (self *SQLStorage) GetCDRs(qryFltr *utils.CDRsFilter) ([]*CDR, int64, error
|
||||
Supplier: result.Supplier,
|
||||
DisconnectCause: result.DisconnectCause,
|
||||
ExtraFields: extraFieldsMp,
|
||||
RunID: result.RunID,
|
||||
CostSource: result.CostSource,
|
||||
Cost: result.Cost,
|
||||
CostDetails: &callCost,
|
||||
ExtraInfo: result.ExtraInfo,
|
||||
}
|
||||
if ccTimespans != nil {
|
||||
storCdr.CostDetails = &CallCost{
|
||||
Direction: result.Direction,
|
||||
Category: result.Category,
|
||||
Tenant: result.Tenant,
|
||||
Subject: result.Subject,
|
||||
Account: result.Account,
|
||||
Destination: result.Destination,
|
||||
TOR: result.Tor,
|
||||
Cost: result.Cost,
|
||||
Timespans: ccTimespans,
|
||||
}
|
||||
}
|
||||
//if !result.Cost.Valid { //There was no cost provided, will fakely insert 0 if we do not handle it and reflect on re-rating
|
||||
storCdr.Cost = -1
|
||||
//}
|
||||
cdrs = append(cdrs, storCdr)
|
||||
}
|
||||
return cdrs, 0, nil
|
||||
|
||||
@@ -16,14 +16,16 @@ 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 engine
|
||||
package general_tests
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"path"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/rpcclient"
|
||||
)
|
||||
@@ -31,12 +33,10 @@ import (
|
||||
var cdrsMasterCfgPath, cdrsSlaveCfgPath string
|
||||
var cdrsMasterCfg, cdrsSlaveCfg *config.CGRConfig
|
||||
|
||||
//var cdrsHttpJsonRpc *rpcclient.RpcClient
|
||||
|
||||
var waitRater = 500
|
||||
var testIntegration = flag.Bool("integration", false, "Perform the tests in integration mode, not by default.") // This flag will be passed here via "go test -local" args
|
||||
|
||||
func TestCdrsInitConfig(t *testing.T) {
|
||||
if !*testLocal {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
var err error
|
||||
@@ -52,45 +52,45 @@ func TestCdrsInitConfig(t *testing.T) {
|
||||
|
||||
// InitDb so we can rely on count
|
||||
func TestCdrsInitCdrDb(t *testing.T) {
|
||||
if !*testLocal {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
if err := InitStorDb(cdrsMasterCfg); err != nil {
|
||||
if err := engine.InitStorDb(cdrsMasterCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := InitStorDb(cdrsSlaveCfg); err != nil {
|
||||
if err := engine.InitStorDb(cdrsSlaveCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCdrsStartMasterEngine(t *testing.T) {
|
||||
if !*testLocal {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
if _, err := StopStartEngine(cdrsMasterCfgPath, waitRater); err != nil {
|
||||
if _, err := engine.StopStartEngine(cdrsMasterCfgPath, *waitRater); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCdrsStartSlaveEngine(t *testing.T) {
|
||||
if !*testLocal {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
if _, err := StartEngine(cdrsSlaveCfgPath, waitRater); err != nil {
|
||||
if _, err := engine.StartEngine(cdrsSlaveCfgPath, *waitRater); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Connect rpc client to rater
|
||||
func TestCdrsHttpCdrReplication(t *testing.T) {
|
||||
if !*testLocal {
|
||||
if !*testIntegration {
|
||||
return
|
||||
}
|
||||
cdrsMasterRpc, err := rpcclient.NewRpcClient("tcp", cdrsMasterCfg.RPCJSONListen, 1, 1, "json", nil)
|
||||
if err != nil {
|
||||
t.Fatal("Could not connect to rater: ", err.Error())
|
||||
}
|
||||
testCdr1 := &CDR{CGRID: utils.Sha1("httpjsonrpc1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
testCdr1 := &engine.CDR{CGRID: utils.Sha1("httpjsonrpc1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
|
||||
TOR: utils.VOICE, OriginID: "httpjsonrpc1", OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.META_PSEUDOPREPAID,
|
||||
Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
|
||||
SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
|
||||
@@ -102,13 +102,13 @@ func TestCdrsHttpCdrReplication(t *testing.T) {
|
||||
} else if reply != utils.OK {
|
||||
t.Error("Unexpected reply received: ", reply)
|
||||
}
|
||||
time.Sleep(time.Duration(waitRater) * time.Millisecond)
|
||||
time.Sleep(time.Duration(*waitRater) * time.Millisecond)
|
||||
cdrsSlaveRpc, err := rpcclient.NewRpcClient("tcp", "127.0.0.1:12012", 1, 1, "json", nil)
|
||||
if err != nil {
|
||||
t.Fatal("Could not connect to rater: ", err.Error())
|
||||
}
|
||||
// ToDo: Fix cdr_http to be compatible with rest of processCdr methods
|
||||
var rcvedCdrs []*ExternalCDR
|
||||
var rcvedCdrs []*engine.ExternalCDR
|
||||
if err := cdrsSlaveRpc.Call("ApierV2.GetCdrs", utils.RPCCDRsFilter{CGRIDs: []string{testCdr1.CGRID}, RunIDs: []string{utils.META_DEFAULT}}, &rcvedCdrs); err != nil {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
} else if len(rcvedCdrs) != 1 {
|
||||
@@ -8,8 +8,8 @@ ap1=$?
|
||||
echo 'go test github.com/cgrates/cgrates/apier/v2 -local'
|
||||
go test github.com/cgrates/cgrates/apier/v2 -local
|
||||
ap2=$?
|
||||
echo 'go test github.com/cgrates/cgrates/engine -local'
|
||||
go test github.com/cgrates/cgrates/engine -local
|
||||
echo 'go test github.com/cgrates/cgrates/engine -local -integration'
|
||||
go test github.com/cgrates/cgrates/engine -local -integration
|
||||
en=$?
|
||||
echo 'go test github.com/cgrates/cgrates/cdrc -local'
|
||||
go test github.com/cgrates/cgrates/cdrc -local
|
||||
@@ -18,8 +18,10 @@ echo 'go test github.com/cgrates/cgrates/config -local'
|
||||
go test github.com/cgrates/cgrates/config -local
|
||||
cfg=$?
|
||||
echo 'go test github.com/cgrates/cgrates/utils -local'
|
||||
echo 'go test github.com/cgrates/cgrates/general_tests -local'
|
||||
go test github.com/cgrates/cgrates/general_tests -local
|
||||
go test github.com/cgrates/cgrates/utils -local
|
||||
utl=$?
|
||||
echo 'go test github.com/cgrates/cgrates/general_tests -local -integration'
|
||||
go test github.com/cgrates/cgrates/general_tests -local -integration
|
||||
gnr=$?
|
||||
echo 'go test github.com/cgrates/cgrates/agents -integration'
|
||||
go test github.com/cgrates/cgrates/agents -integration
|
||||
@@ -29,4 +31,4 @@ agts=$?
|
||||
|
||||
|
||||
|
||||
exit $gen && $ap1 && $ap2 && $en && $cdrc && $cfg && $gnr && $agts
|
||||
exit $gen && $ap1 && $ap2 && $en && $cdrc && $cfg && $utl && $gnr && $agts
|
||||
|
||||
@@ -262,6 +262,7 @@ const (
|
||||
MatchEndPrefix = "$"
|
||||
SMG = "SMG"
|
||||
MetaGrouped = "*grouped"
|
||||
MetaRaw = "*raw"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
Reference in New Issue
Block a user