mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Complete set of cost simulation for tutorial2
This commit is contained in:
166
data/conf/samples/tutmongo2/cgrates.json
Normal file
166
data/conf/samples/tutmongo2/cgrates.json
Normal file
@@ -0,0 +1,166 @@
|
||||
{
|
||||
// CGRateS Configuration file
|
||||
//
|
||||
|
||||
|
||||
"general": {
|
||||
"node_id": "CGRateSTutorial",
|
||||
"log_level": 7
|
||||
},
|
||||
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080",
|
||||
},
|
||||
|
||||
|
||||
"data_db": {
|
||||
"db_type": "mongo",
|
||||
"db_port": 27017,
|
||||
},
|
||||
|
||||
|
||||
"stor_db": {
|
||||
"db_type": "mongo",
|
||||
"db_port": 27017,
|
||||
},
|
||||
|
||||
|
||||
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
"cdrs_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"cdrs": {
|
||||
"enabled": true,
|
||||
"extra_fields": ["PayPalAccount", "LCRProfile", "ResourceID"],
|
||||
"chargers_conns":[
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"},
|
||||
],
|
||||
"store_cdrs": true,
|
||||
"online_cdr_exports": []
|
||||
},
|
||||
|
||||
|
||||
"cdre": {
|
||||
"amqp_localhost": {
|
||||
"export_format": "*amqp_json_map",
|
||||
"export_path": "amqp://guest:guest@localhost:5672/?queue_id=cgrates_cdrs",
|
||||
"content_fields": [
|
||||
{"field_id": "CGRID", "type": "*variable", "value": "~CGRID"},
|
||||
{"field_id": "RunID", "type": "*variable", "value": "~RunID"},
|
||||
{"field_id": "ToR", "type": "*variable", "value": "~ToR"},
|
||||
{"field_id": "OriginID", "type": "*variable", "value": "~OriginID"},
|
||||
{"field_id": "OriginHost", "type": "*variable", "value": "~OriginHost"},
|
||||
{"field_id": "RequestType", "type": "*variable", "value": "~RequestType", },
|
||||
{"field_id": "Tenant", "type": "*variable", "value": "~Tenant"},
|
||||
{"field_id": "Category", "type": "*variable", "value": "~Category"},
|
||||
{"field_id": "Account", "type": "*variable", "value": "~Account"},
|
||||
{"field_id": "Destination", "type": "*variable", "value": "~Destination"},
|
||||
{"field_id": "SetupTime", "type": "*variable", "value": "~SetupTime"},
|
||||
{"field_id": "AnswerTime", "type": "*variable", "value": "~AnswerTime"},
|
||||
{"field_id": "Usage", "type": "*variable", "value": "~Usage"},
|
||||
{"field_id": "Cost", "type": "*variable", "value": "~Cost"},
|
||||
{"field_id": "PayPalAccount", "type": "*variable", "value": "~PayPalAccount"},
|
||||
{"field_id": "LCRProfile", "type": "*variable", "value": "~LCRProfile", },
|
||||
{"field_id": "ResourceID", "type": "*variable", "value": "~ResourceID", },
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
"cdrc": [
|
||||
{
|
||||
"id": "tutorial_csv_cdr",
|
||||
"enabled": true,
|
||||
"cdr_source_id": "cgr_tutorial",
|
||||
"content_fields":[
|
||||
{"field_id": "OriginID", "type": "*composed", "value": "~3", "mandatory": true},
|
||||
{"field_id": "Account", "type": "*composed", "value": "~8", "mandatory": true},
|
||||
{"field_id": "Destination", "type": "*composed", "value": "~10", "mandatory": true},
|
||||
{"field_id": "SetupTime", "type": "*composed", "value": "~11", "mandatory": true},
|
||||
{"field_id": "AnswerTime", "type": "*composed", "value": "~12", "mandatory": true},
|
||||
{"field_id": "Usage", "type": "*composed", "value": "~13", "mandatory": true},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
|
||||
"sessions": {
|
||||
"enabled": true,
|
||||
"resources_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"}
|
||||
],
|
||||
"suppliers_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"}
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"attributes": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"]
|
||||
},
|
||||
|
||||
|
||||
"chargers": {
|
||||
"enabled": true,
|
||||
"attributes_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"}
|
||||
],
|
||||
"string_indexed_fields": ["Account"]
|
||||
},
|
||||
|
||||
|
||||
"resources": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"}
|
||||
],
|
||||
"string_indexed_fields": ["Account"]
|
||||
},
|
||||
|
||||
|
||||
"stats": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport":"*json"}
|
||||
],
|
||||
"string_indexed_fields": ["Account"]
|
||||
},
|
||||
|
||||
|
||||
"thresholds": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["Account"]
|
||||
},
|
||||
|
||||
|
||||
"suppliers": {
|
||||
"enabled": true,
|
||||
"string_indexed_fields": ["LCRProfile"],
|
||||
"prefix_indexed_fields":["Destination"],
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
@@ -61,6 +61,12 @@ func (rs *Responder) usageAllowed(tor string, reqUsage time.Duration) (allowed b
|
||||
RPC method thet provides the external RPC interface for getting the rating information.
|
||||
*/
|
||||
func (rs *Responder) GetCost(arg *CallDescriptor, reply *CallCost) (err error) {
|
||||
if arg.Tenant == "" {
|
||||
arg.Tenant = config.CgrConfig().GeneralCfg().DefaultTenant
|
||||
}
|
||||
if arg.Category == "" {
|
||||
arg.Category = config.CgrConfig().GeneralCfg().DefaultCategory
|
||||
}
|
||||
if arg.Subject == "" {
|
||||
arg.Subject = arg.Account
|
||||
}
|
||||
|
||||
252
general_tests/tutorial2_it_test.go
Normal file
252
general_tests/tutorial2_it_test.go
Normal file
@@ -0,0 +1,252 @@
|
||||
// +build integration
|
||||
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
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 general_tests
|
||||
|
||||
import (
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"path"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v1 "github.com/cgrates/cgrates/apier/v1"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
tutCfgPath string
|
||||
tutCfg *config.CGRConfig
|
||||
tutRpc *rpc.Client
|
||||
tutCfgDir string //run tests for specific configuration
|
||||
tutDelay int
|
||||
)
|
||||
|
||||
var sTutTests = []func(t *testing.T){
|
||||
testTutLoadConfig,
|
||||
testTutResetDB,
|
||||
testTutStartEngine,
|
||||
testTutRpcConn,
|
||||
testTutFromFolder,
|
||||
testTutGetCost,
|
||||
testTutStopEngine,
|
||||
}
|
||||
|
||||
//Test start here
|
||||
func TestTutorial2MySQL(t *testing.T) {
|
||||
tutCfgDir = "tutmysql2"
|
||||
for _, stest := range sTutTests {
|
||||
t.Run(tutCfgDir, stest)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTutorial2Mongo(t *testing.T) {
|
||||
tutCfgDir = "tutmongo2"
|
||||
for _, stest := range sTutTests {
|
||||
t.Run(tutCfgDir, stest)
|
||||
}
|
||||
}
|
||||
|
||||
func testTutLoadConfig(t *testing.T) {
|
||||
var err error
|
||||
tutCfgPath = path.Join(*dataDir, "conf", "samples", tutCfgDir)
|
||||
if tutCfg, err = config.NewCGRConfigFromFolder(tutCfgPath); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
switch tutCfgDir {
|
||||
default:
|
||||
tutDelay = 2000
|
||||
}
|
||||
}
|
||||
|
||||
func testTutResetDB(t *testing.T) {
|
||||
if err := engine.InitDataDb(tutCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := engine.InitStorDb(tutCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testTutStartEngine(t *testing.T) {
|
||||
if _, err := engine.StopStartEngine(tutCfgPath, tutDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testTutRpcConn(t *testing.T) {
|
||||
var err error
|
||||
if tutRpc, err = jsonrpc.Dial("tcp", tutCfg.ListenCfg().RPCJSONListen); err != nil {
|
||||
t.Fatal("could not connect to rater: ", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func testTutFromFolder(t *testing.T) {
|
||||
var reply string
|
||||
attrs := &utils.AttrLoadTpFromFolder{
|
||||
FolderPath: path.Join(*dataDir, "tariffplans", "tutorial2")}
|
||||
if err := tutRpc.Call(utils.ApierV1LoadTariffPlanFromFolder,
|
||||
attrs, &reply); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
|
||||
func testTutGetCost(t *testing.T) {
|
||||
// Standard pricing for 1001->1002
|
||||
attrs := v1.AttrGetCost{
|
||||
Subject: "1001",
|
||||
Destination: "1002",
|
||||
AnswerTime: "*now",
|
||||
Usage: "45s",
|
||||
}
|
||||
var rply *engine.EventCost
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil {
|
||||
t.Error("Unexpected nil error received: ", err.Error())
|
||||
} else if *rply.Cost != 0.45 { // FixMe: missing ConnectFee out of Cost
|
||||
t.Errorf("Unexpected cost received: %f", *rply.Cost)
|
||||
}
|
||||
// Fallback pricing from *any, Usage will be rounded to 60s
|
||||
attrs = v1.AttrGetCost{
|
||||
Subject: "1001",
|
||||
Destination: "1003",
|
||||
AnswerTime: "2019-03-11T09:00:00Z",
|
||||
Usage: "45s",
|
||||
}
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil {
|
||||
t.Error("Unexpected nil error received: ", err.Error())
|
||||
} else if *rply.Cost != 1.2 { // FixMe: missing ConnectFee out of Cost
|
||||
t.Errorf("Unexpected cost received: %f", *rply.Cost)
|
||||
}
|
||||
// Fallback pricing from *any, Usage will be rounded to 60s
|
||||
attrs = v1.AttrGetCost{
|
||||
Subject: "1001",
|
||||
Destination: "1003",
|
||||
AnswerTime: "2019-03-11T21:00:00Z",
|
||||
Usage: "45s",
|
||||
}
|
||||
/*
|
||||
// *any to 2001
|
||||
attrs = v1.AttrGetCost{
|
||||
Subject: "1002",
|
||||
Destination: "2001",
|
||||
AnswerTime: "*now",
|
||||
Usage: "45s",
|
||||
}
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil {
|
||||
t.Error("Unexpected nil error received: ", err.Error())
|
||||
} else if *rply.Cost != 1.2 { // FixMe: missing ConnectFee out of Cost
|
||||
t.Errorf("Unexpected cost received: %f", *rply.Cost)
|
||||
}
|
||||
*/
|
||||
// *any to 2001 on NEW_YEAR
|
||||
attrs = v1.AttrGetCost{
|
||||
Subject: "1002",
|
||||
Destination: "2001",
|
||||
AnswerTime: "2020-01-01T21:00:00Z",
|
||||
Usage: "45s",
|
||||
}
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil {
|
||||
t.Error("Unexpected nil error received: ", err.Error())
|
||||
} else if *rply.Cost != 0.45 {
|
||||
t.Errorf("Unexpected cost received: %f", *rply.Cost)
|
||||
}
|
||||
// Fallback pricing from *any, Usage will be rounded to 60s
|
||||
attrs = v1.AttrGetCost{
|
||||
Subject: "1001",
|
||||
Destination: "1003",
|
||||
AnswerTime: "2019-03-11T21:00:00Z",
|
||||
Usage: "45s",
|
||||
}
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil {
|
||||
t.Error("Unexpected nil error received: ", err.Error())
|
||||
} else if *rply.Cost != 0.45 { // FixMe: missing ConnectFee out of Cost
|
||||
t.Errorf("Unexpected cost received: %f", *rply.Cost)
|
||||
}
|
||||
// Unauthorized destination
|
||||
attrs = v1.AttrGetCost{
|
||||
Subject: "1001",
|
||||
Destination: "4003",
|
||||
AnswerTime: "2019-03-11T09:00:00Z",
|
||||
Usage: "1m",
|
||||
}
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err == nil ||
|
||||
err.Error() != "SERVER_ERROR: UNAUTHORIZED_DESTINATION" {
|
||||
t.Error("Unexpected nil error received: ", err)
|
||||
}
|
||||
// Data charging
|
||||
attrs = v1.AttrGetCost{
|
||||
Category: "data",
|
||||
Subject: "1001",
|
||||
AnswerTime: "*now",
|
||||
Usage: "2048",
|
||||
}
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil {
|
||||
t.Error("Unexpected nil error received: ", err.Error())
|
||||
} else if *rply.Cost != 2.0 { // FixMe: missing ConnectFee out of Cost
|
||||
t.Errorf("Unexpected cost received: %f", *rply.Cost)
|
||||
}
|
||||
// SMS charging 1002
|
||||
attrs = v1.AttrGetCost{
|
||||
Category: "sms",
|
||||
Subject: "1003",
|
||||
Destination: "1002",
|
||||
AnswerTime: "*now",
|
||||
Usage: "1",
|
||||
}
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil {
|
||||
t.Error("Unexpected nil error received: ", err.Error())
|
||||
} else if *rply.Cost != 0.1 {
|
||||
t.Errorf("Unexpected cost received: %f", *rply.Cost)
|
||||
}
|
||||
// SMS charging 10
|
||||
attrs = v1.AttrGetCost{
|
||||
Category: "sms",
|
||||
Subject: "1001",
|
||||
Destination: "1003",
|
||||
AnswerTime: "*now",
|
||||
Usage: "1",
|
||||
}
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err != nil {
|
||||
t.Error("Unexpected nil error received: ", err.Error())
|
||||
} else if *rply.Cost != 0.2 {
|
||||
t.Errorf("Unexpected cost received: %f", *rply.Cost)
|
||||
}
|
||||
// SMS charging UNAUTHORIZED
|
||||
attrs = v1.AttrGetCost{
|
||||
Category: "sms",
|
||||
Subject: "1001",
|
||||
Destination: "2001",
|
||||
AnswerTime: "*now",
|
||||
Usage: "1",
|
||||
}
|
||||
if err := tutRpc.Call(utils.ApierV1GetCost, attrs, &rply); err == nil ||
|
||||
err.Error() != "SERVER_ERROR: UNAUTHORIZED_DESTINATION" {
|
||||
t.Error("Unexpected nil error received: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testTutStopEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(tutDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
@@ -686,15 +686,17 @@ const (
|
||||
|
||||
// ApierV1 APIs
|
||||
const (
|
||||
ApierV1ComputeFilterIndexes = "ApierV1.ComputeFilterIndexes"
|
||||
ApierV1ReloadCache = "ApierV1.ReloadCache"
|
||||
ApierV1ReloadScheduler = "ApierV1.ReloadScheduler"
|
||||
ApierV1Ping = "ApierV1.Ping"
|
||||
ApierV1SetDispatcherProfile = "ApierV1.SetDispatcherProfile"
|
||||
ApierV1GetDispatcherProfile = "ApierV1.GetDispatcherProfile"
|
||||
ApierV1RemoveDispatcherProfile = "ApierV1.RemoveDispatcherProfile"
|
||||
ApierV1GetResource = "ApierV1.GetResource"
|
||||
ApierV1GetEventCost = "ApierV1.GetEventCost"
|
||||
ApierV1ComputeFilterIndexes = "ApierV1.ComputeFilterIndexes"
|
||||
ApierV1ReloadCache = "ApierV1.ReloadCache"
|
||||
ApierV1ReloadScheduler = "ApierV1.ReloadScheduler"
|
||||
ApierV1Ping = "ApierV1.Ping"
|
||||
ApierV1SetDispatcherProfile = "ApierV1.SetDispatcherProfile"
|
||||
ApierV1GetDispatcherProfile = "ApierV1.GetDispatcherProfile"
|
||||
ApierV1RemoveDispatcherProfile = "ApierV1.RemoveDispatcherProfile"
|
||||
ApierV1GetResource = "ApierV1.GetResource"
|
||||
ApierV1GetEventCost = "ApierV1.GetEventCost"
|
||||
ApierV1LoadTariffPlanFromFolder = "ApierV1.LoadTariffPlanFromFolder"
|
||||
ApierV1GetCost = "ApierV1.GetCost"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user