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:
DanB
2015-12-13 17:28:55 +01:00
parent 16beb55df8
commit eb2e8f6876
23 changed files with 324 additions and 3054 deletions

View File

@@ -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())
}
}

View File

@@ -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())
}
}

View File

@@ -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())
}
}

View 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
},
}

View 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
},
}

View File

@@ -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)
);

View File

@@ -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;

View File

@@ -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

View File

@@ -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)
}
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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

View File

@@ -415,7 +415,7 @@ type TBLCDRs struct {
DisconnectCause string
ExtraFields string
Cost float64
Timespans string
CostDetails string
CostSource string
ExtraInfo string
CreatedAt time.Time

View 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
}

View File

@@ -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)

View File

@@ -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])
}
}
}

View File

@@ -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
}

View File

@@ -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])
}
}
}

View File

@@ -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])
}
}
}

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -262,6 +262,7 @@ const (
MatchEndPrefix = "$"
SMG = "SMG"
MetaGrouped = "*grouped"
MetaRaw = "*raw"
)
var (