mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Add integration tests for dispatcher
This commit is contained in:
committed by
Dan Christian Bogos
parent
909f97cfb6
commit
77d01b02e3
@@ -38,18 +38,10 @@ func (dT *DispatcherThresholdSv1) Ping(ign string, reply *string) error {
|
||||
return dT.dS.ThresholdSv1Ping(ign, reply)
|
||||
}
|
||||
|
||||
/* To be implemented in console
|
||||
// GetThresholdIDs implements ThresholdSv1GetThresholdIDs
|
||||
func (dT *DispatcherThresholdSv1) GetThresholdIDs(tenant string,
|
||||
tIDs *[]string) error {
|
||||
return dT.dS.ThresholdSv1GetThresholdIDs(tenant, tIDs)
|
||||
}
|
||||
*/
|
||||
|
||||
// GetThreshold implements ThresholdSv1GetThreshold
|
||||
// GetThresholdsForEvent implements ThresholdSv1GetThresholdsForEvent
|
||||
func (dT *DispatcherThresholdSv1) GetThresholdsForEvent(tntID *dispatcher.ArgsProcessEventWithApiKey,
|
||||
t *engine.Threshold) error {
|
||||
return dT.dS.ThresholdSv1GetThresholdForEvent(tntID, t)
|
||||
t *engine.Thresholds) error {
|
||||
return dT.dS.ThresholdSv1GetThresholdsForEvent(tntID, t)
|
||||
}
|
||||
|
||||
// ProcessEvent implements ThresholdSv1ProcessEvent
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080",
|
||||
"rpc_json": ":2112",
|
||||
"rpc_gob": ":2113",
|
||||
"http": ":2180",
|
||||
},
|
||||
|
||||
"data_db": { // database used to store runtime data (eg: accounts, cdr stats)
|
||||
@@ -32,32 +32,27 @@
|
||||
},
|
||||
|
||||
|
||||
"resources": { // Resource service (*new)
|
||||
"enabled": false, // starts ResourceLimiter service: <true|false>.
|
||||
},
|
||||
|
||||
|
||||
"dispatcher":{
|
||||
"enabled": true, // starts DispatcherS service: <true|false>.
|
||||
"rals_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "192.168.56.204:2012", "transport": "*json"},
|
||||
{"address": "192.168.56.203:2012", "transport": "*json"},
|
||||
],
|
||||
"thresholds_conns": [
|
||||
{"address": "192.168.56.204:2012", "transport": "*json"},
|
||||
{"address": "192.168.56.203:2012", "transport": "*json"},
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "192.168.56.204:2012", "transport": "*json"},
|
||||
{"address": "192.168.56.203:2012", "transport": "*json"},
|
||||
],
|
||||
"suppliers_conns": [
|
||||
{"address": "192.168.56.204:2012", "transport": "*json"},
|
||||
{"address": "192.168.56.203:2012", "transport": "*json"},
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "192.168.56.204:2012", "transport": "*json"},
|
||||
{"address": "192.168.56.203:2012", "transport": "*json"},
|
||||
],
|
||||
"dispatching_strategy":"*random",
|
||||
"dispatching_strategy":"*first",
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package dispatcher
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
@@ -41,7 +39,6 @@ func (dS *DispatcherService) AttributeSv1GetAttributeForEvent(args *CGREvWithApi
|
||||
Tenant: args.Tenant,
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Context: utils.StringPointer(utils.MetaAuth),
|
||||
Time: utils.TimePointer(time.Now()),
|
||||
Event: map[string]interface{}{
|
||||
utils.APIKey: args.APIKey,
|
||||
},
|
||||
@@ -70,7 +67,6 @@ func (dS *DispatcherService) AttributeSv1ProcessEvent(args *CGREvWithApiKey,
|
||||
Tenant: args.Tenant,
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Context: utils.StringPointer(utils.MetaAuth),
|
||||
Time: utils.TimePointer(time.Now()),
|
||||
Event: map[string]interface{}{
|
||||
utils.APIKey: args.APIKey,
|
||||
},
|
||||
|
||||
301
dispatcher/attributes_it_test.go
Executable file
301
dispatcher/attributes_it_test.go
Executable file
@@ -0,0 +1,301 @@
|
||||
// +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 dispatcher
|
||||
|
||||
import (
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
dspAttrCfgPath string
|
||||
dspAttrCfg *config.CGRConfig
|
||||
dspAttrRPC *rpc.Client
|
||||
instAttrCfgPath string
|
||||
instAttrCfg *config.CGRConfig
|
||||
instAttrRPC *rpc.Client
|
||||
)
|
||||
|
||||
var sTestsDspAttr = []func(t *testing.T){
|
||||
testDspAttrInitCfg,
|
||||
testDspAttrInitDataDb,
|
||||
testDspAttrResetStorDb,
|
||||
testDspAttrStartEngine,
|
||||
testDspAttrRPCConn,
|
||||
testDspAttrPing,
|
||||
testDspAttrLoadData,
|
||||
testDspAttrAddAttributesWithPermision,
|
||||
testDspAttrTestAuthKey,
|
||||
testDspAttrAddAttributesWithPermision2,
|
||||
testDspAttrTestAuthKey2,
|
||||
testDspAttrKillEngine,
|
||||
}
|
||||
|
||||
//Test start here
|
||||
func TestDspAttributeS(t *testing.T) {
|
||||
for _, stest := range sTestsDspAttr {
|
||||
t.Run("", stest)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspAttrInitCfg(t *testing.T) {
|
||||
var err error
|
||||
dspAttrCfgPath = path.Join(dspDataDir, "conf", "samples", "dispatcher")
|
||||
dspAttrCfg, err = config.NewCGRConfigFromFolder(dspAttrCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
dspAttrCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(dspAttrCfg)
|
||||
instAttrCfgPath = path.Join(dspDataDir, "conf", "samples", "tutmysql")
|
||||
instAttrCfg, err = config.NewCGRConfigFromFolder(instAttrCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
instAttrCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(instAttrCfg)
|
||||
}
|
||||
|
||||
func testDspAttrInitDataDb(t *testing.T) {
|
||||
if err := engine.InitDataDb(instAttrCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe out the cdr database
|
||||
func testDspAttrResetStorDb(t *testing.T) {
|
||||
if err := engine.InitStorDb(instAttrCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Start CGR Engine
|
||||
func testDspAttrStartEngine(t *testing.T) {
|
||||
if _, err := engine.StartEngine(instAttrCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := engine.StartEngine(dspAttrCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Connect rpc client to rater
|
||||
func testDspAttrRPCConn(t *testing.T) {
|
||||
var err error
|
||||
instAttrRPC, err = jsonrpc.Dial("tcp", instAttrCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dspAttrRPC, err = jsonrpc.Dial("tcp", dspAttrCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func testDspAttrPing(t *testing.T) {
|
||||
var reply string
|
||||
if err := instAttrRPC.Call(utils.AttributeSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
if err := dspAttrRPC.Call(utils.AttributeSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspAttrLoadData(t *testing.T) {
|
||||
var reply string
|
||||
attrs := &utils.AttrLoadTpFromFolder{
|
||||
FolderPath: path.Join(dspDataDir, "tariffplans", "tutorial2")}
|
||||
if err := instAttrRPC.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
|
||||
func testDspAttrAddAttributesWithPermision(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "ThresholdSv1.GetThAttrholdsForEvent",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var Attrult string
|
||||
if err := instAttrRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &Attrult); err != nil {
|
||||
t.Error(err)
|
||||
} else if Attrult != utils.OK {
|
||||
t.Error("Unexpected reply returned", Attrult)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instAttrRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspAttrTestAuthKey(t *testing.T) {
|
||||
args := &CGREvWithApiKey{
|
||||
APIKey: "12345",
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "testAttributeSGetAttributeForEvent",
|
||||
Context: utils.StringPointer("simpleauth"),
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1001",
|
||||
},
|
||||
},
|
||||
}
|
||||
var attrReply *engine.AttributeProfile
|
||||
if err := dspAttrRPC.Call(utils.AttributeSv1GetAttributeForEvent,
|
||||
args, &attrReply); err.Error() != utils.ErrUnauthorizedApi.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspAttrAddAttributesWithPermision2(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "AttributeSv1.GetAttributeForEvent;AttributeSv1.ProcessEvent",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var Attrult string
|
||||
if err := instAttrRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &Attrult); err != nil {
|
||||
t.Error(err)
|
||||
} else if Attrult != utils.OK {
|
||||
t.Error("Unexpected reply returned", Attrult)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instAttrRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspAttrTestAuthKey2(t *testing.T) {
|
||||
args := &CGREvWithApiKey{
|
||||
APIKey: "12345",
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "testAttributeSGetAttributeForEvent",
|
||||
Context: utils.StringPointer("simpleauth"),
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1001",
|
||||
},
|
||||
},
|
||||
}
|
||||
eAttrPrf := &engine.AttributeProfile{
|
||||
Tenant: args.Tenant,
|
||||
ID: "ATTR_1001_SIMPLEAUTH",
|
||||
FilterIDs: []string{"*string:Account:1001"},
|
||||
Contexts: []string{"simpleauth"},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: "Password",
|
||||
Initial: utils.ANY,
|
||||
Substitute: "CGRateS.org",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20.0,
|
||||
}
|
||||
var attrReply *engine.AttributeProfile
|
||||
if err := dspAttrRPC.Call(utils.AttributeSv1GetAttributeForEvent,
|
||||
args, &attrReply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eAttrPrf, attrReply) {
|
||||
t.Errorf("Expecting: %s, received: %s", utils.ToJSON(eAttrPrf), utils.ToJSON(attrReply))
|
||||
}
|
||||
|
||||
eRply := &engine.AttrSProcessEventReply{
|
||||
MatchedProfile: "ATTR_1001_SIMPLEAUTH",
|
||||
AlteredFields: []string{"Password"},
|
||||
CGREvent: &utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "testAttributeSGetAttributeForEvent",
|
||||
Context: utils.StringPointer("simpleauth"),
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1001",
|
||||
"Password": "CGRateS.org",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var rplyEv engine.AttrSProcessEventReply
|
||||
if err := dspAttrRPC.Call(utils.AttributeSv1ProcessEvent,
|
||||
args, &rplyEv); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eRply, &rplyEv) {
|
||||
t.Errorf("Expecting: %s, received: %s",
|
||||
utils.ToJSON(eRply), utils.ToJSON(rplyEv))
|
||||
}
|
||||
}
|
||||
|
||||
func testDspAttrKillEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
274
dispatcher/resources_it_test.go
Executable file
274
dispatcher/resources_it_test.go
Executable file
@@ -0,0 +1,274 @@
|
||||
// +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 dispatcher
|
||||
|
||||
import (
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
dspResCfgPath string
|
||||
dspResCfg *config.CGRConfig
|
||||
dspResRPC *rpc.Client
|
||||
instResCfgPath string
|
||||
instResCfg *config.CGRConfig
|
||||
instResRPC *rpc.Client
|
||||
)
|
||||
|
||||
var sTestsDspRes = []func(t *testing.T){
|
||||
testDspResInitCfg,
|
||||
testDspResInitDataDb,
|
||||
testDspResResetStorDb,
|
||||
testDspResStartEngine,
|
||||
testDspResRPCConn,
|
||||
testDspResPing,
|
||||
testDspResLoadData,
|
||||
testDspResAddAttributesWithPermision,
|
||||
testDspResTestAuthKey,
|
||||
testDspResAddAttributesWithPermision2,
|
||||
testDspResTestAuthKey2,
|
||||
testDspResKillEngine,
|
||||
}
|
||||
|
||||
//Test start here
|
||||
func TestDspResourceS(t *testing.T) {
|
||||
for _, stest := range sTestsDspRes {
|
||||
t.Run("", stest)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspResInitCfg(t *testing.T) {
|
||||
var err error
|
||||
dspResCfgPath = path.Join(dspDataDir, "conf", "samples", "dispatcher")
|
||||
dspResCfg, err = config.NewCGRConfigFromFolder(dspResCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
dspResCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(dspResCfg)
|
||||
instResCfgPath = path.Join(dspDataDir, "conf", "samples", "tutmysql")
|
||||
instResCfg, err = config.NewCGRConfigFromFolder(instResCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
instResCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(instResCfg)
|
||||
}
|
||||
|
||||
func testDspResInitDataDb(t *testing.T) {
|
||||
if err := engine.InitDataDb(instResCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe out the cdr database
|
||||
func testDspResResetStorDb(t *testing.T) {
|
||||
if err := engine.InitStorDb(instResCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Start CGR Engine
|
||||
func testDspResStartEngine(t *testing.T) {
|
||||
if _, err := engine.StartEngine(instResCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := engine.StartEngine(dspResCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Connect rpc client to rater
|
||||
func testDspResRPCConn(t *testing.T) {
|
||||
var err error
|
||||
instResRPC, err = jsonrpc.Dial("tcp", instResCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dspResRPC, err = jsonrpc.Dial("tcp", dspResCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func testDspResPing(t *testing.T) {
|
||||
var reply string
|
||||
if err := instResRPC.Call(utils.ResourceSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
if err := dspResRPC.Call(utils.ResourceSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspResLoadData(t *testing.T) {
|
||||
var reply string
|
||||
attrs := &utils.AttrLoadTpFromFolder{
|
||||
FolderPath: path.Join(dspDataDir, "tariffplans", "tutorial2")}
|
||||
if err := instResRPC.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
|
||||
func testDspResAddAttributesWithPermision(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "ThresholdSv1.GetThresholdsForEvent",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var result string
|
||||
if err := instResRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instResRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspResTestAuthKey(t *testing.T) {
|
||||
var rs *engine.Resources
|
||||
args := &ArgsV1ResUsageWithApiKey{
|
||||
APIKey: "12345",
|
||||
ArgRSv1ResourceUsage: utils.ArgRSv1ResourceUsage{
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1001",
|
||||
utils.Destination: "1002",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := dspResRPC.Call(utils.ResourceSv1GetResourcesForEvent,
|
||||
args, &rs); err.Error() != utils.ErrUnauthorizedApi.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspResAddAttributesWithPermision2(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "ThresholdSv1.ProcessEvent;ResourceSv1.GetResourcesForEvent",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var result string
|
||||
if err := instResRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instResRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspResTestAuthKey2(t *testing.T) {
|
||||
var rs *engine.Resources
|
||||
args := &ArgsV1ResUsageWithApiKey{
|
||||
APIKey: "12345",
|
||||
ArgRSv1ResourceUsage: utils.ArgRSv1ResourceUsage{
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1001",
|
||||
utils.Destination: "1002",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
eRs := &engine.Resources{
|
||||
&engine.Resource{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ResGroup2",
|
||||
Usages: map[string]*engine.ResourceUsage{},
|
||||
},
|
||||
}
|
||||
|
||||
if err := dspResRPC.Call(utils.ResourceSv1GetResourcesForEvent,
|
||||
args, &rs); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eRs, rs) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(eRs), utils.ToJSON(rs))
|
||||
}
|
||||
}
|
||||
|
||||
func testDspResKillEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
330
dispatcher/stats_it_test.go
Executable file
330
dispatcher/stats_it_test.go
Executable file
@@ -0,0 +1,330 @@
|
||||
// +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 dispatcher
|
||||
|
||||
import (
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
dspStsCfgPath string
|
||||
dspStsCfg *config.CGRConfig
|
||||
dspStsRPC *rpc.Client
|
||||
instStsCfgPath string
|
||||
instStsCfg *config.CGRConfig
|
||||
instStsRPC *rpc.Client
|
||||
)
|
||||
|
||||
var sTestsDspSts = []func(t *testing.T){
|
||||
testDspStsInitCfg,
|
||||
testDspStsInitDataDb,
|
||||
testDspStsResetStorDb,
|
||||
testDspStsStartEngine,
|
||||
testDspStsRPCConn,
|
||||
testDspStsPing,
|
||||
testDspStsLoadData,
|
||||
testDspStsAddStsibutesWithPermision,
|
||||
testDspStsTestAuthKey,
|
||||
testDspStsAddStsibutesWithPermision2,
|
||||
testDspStsTestAuthKey2,
|
||||
testDspStsKillEngine,
|
||||
}
|
||||
|
||||
//Test start here
|
||||
func TestDspStatS(t *testing.T) {
|
||||
for _, stest := range sTestsDspSts {
|
||||
t.Run("", stest)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspStsInitCfg(t *testing.T) {
|
||||
var err error
|
||||
dspStsCfgPath = path.Join(dspDataDir, "conf", "samples", "dispatcher")
|
||||
dspStsCfg, err = config.NewCGRConfigFromFolder(dspStsCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
dspStsCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(dspStsCfg)
|
||||
instStsCfgPath = path.Join(dspDataDir, "conf", "samples", "tutmysql")
|
||||
instStsCfg, err = config.NewCGRConfigFromFolder(instStsCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
instStsCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(instStsCfg)
|
||||
}
|
||||
|
||||
func testDspStsInitDataDb(t *testing.T) {
|
||||
if err := engine.InitDataDb(instStsCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe out the cdr database
|
||||
func testDspStsResetStorDb(t *testing.T) {
|
||||
if err := engine.InitStorDb(instStsCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Start CGR Engine
|
||||
func testDspStsStartEngine(t *testing.T) {
|
||||
if _, err := engine.StartEngine(instStsCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := engine.StartEngine(dspStsCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Connect rpc client to rater
|
||||
func testDspStsRPCConn(t *testing.T) {
|
||||
var err error
|
||||
instStsRPC, err = jsonrpc.Dial("tcp", instStsCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dspStsRPC, err = jsonrpc.Dial("tcp", dspStsCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func testDspStsPing(t *testing.T) {
|
||||
var reply string
|
||||
if err := instStsRPC.Call(utils.StatSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
if err := dspStsRPC.Call(utils.StatSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspStsLoadData(t *testing.T) {
|
||||
var reply string
|
||||
Stss := &utils.AttrLoadTpFromFolder{
|
||||
FolderPath: path.Join(dspDataDir, "tariffplans", "tutorial2")}
|
||||
if err := instStsRPC.Call("ApierV1.LoadTariffPlanFromFolder", Stss, &reply); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
|
||||
func testDspStsAddStsibutesWithPermision(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "ThresholdSv1.GetThAttrholdsForEvent",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var Attrult string
|
||||
if err := instStsRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &Attrult); err != nil {
|
||||
t.Error(err)
|
||||
} else if Attrult != utils.OK {
|
||||
t.Error("Unexpected reply returned", Attrult)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instStsRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspStsTestAuthKey(t *testing.T) {
|
||||
var reply []string
|
||||
args := CGREvWithApiKey{
|
||||
APIKey: "12345",
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "event1",
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1001",
|
||||
utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
utils.Usage: time.Duration(135 * time.Second),
|
||||
utils.COST: 123.0,
|
||||
utils.PDD: time.Duration(12 * time.Second)}},
|
||||
}
|
||||
if err := dspStsRPC.Call(utils.StatSv1ProcessEvent,
|
||||
args, &reply); err.Error() != utils.ErrUnauthorizedApi.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
args2 := TntIDWithApiKey{
|
||||
APIKey: "12345",
|
||||
TenantID: utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Stats2",
|
||||
},
|
||||
}
|
||||
|
||||
var metrics map[string]string
|
||||
if err := dspStsRPC.Call(utils.StatSv1GetQueueStringMetrics,
|
||||
args2, &metrics); err.Error() != utils.ErrUnauthorizedApi.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspStsAddStsibutesWithPermision2(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "StatSv1.ProcessEvent;StatSv1.GetQueueStringMetrics",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var Attrult string
|
||||
if err := instStsRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &Attrult); err != nil {
|
||||
t.Error(err)
|
||||
} else if Attrult != utils.OK {
|
||||
t.Error("Unexpected reply returned", Attrult)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instStsRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspStsTestAuthKey2(t *testing.T) {
|
||||
var reply []string
|
||||
var metrics map[string]string
|
||||
expected := []string{"Stats2"}
|
||||
args := CGREvWithApiKey{
|
||||
APIKey: "12345",
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "event1",
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1001",
|
||||
utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
utils.Usage: time.Duration(135 * time.Second),
|
||||
utils.COST: 123.0,
|
||||
utils.RunID: utils.DEFAULT_RUNID,
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := dspStsRPC.Call(utils.StatSv1ProcessEvent, args, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(reply, expected) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", expected, reply)
|
||||
}
|
||||
|
||||
args2 := TntIDWithApiKey{
|
||||
APIKey: "12345",
|
||||
TenantID: utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "Stats2",
|
||||
},
|
||||
}
|
||||
expectedMetrics := map[string]string{
|
||||
utils.MetaTCC: "123",
|
||||
utils.MetaTCD: "2m15s",
|
||||
}
|
||||
|
||||
if err := dspStsRPC.Call(utils.StatSv1GetQueueStringMetrics,
|
||||
args2, &metrics); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expectedMetrics, metrics) {
|
||||
t.Errorf("expecting: %+v, received reply: %s", expectedMetrics, metrics)
|
||||
}
|
||||
|
||||
args = CGREvWithApiKey{
|
||||
APIKey: "12345",
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "event1",
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1002",
|
||||
utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC),
|
||||
utils.Usage: time.Duration(45 * time.Second),
|
||||
utils.RunID: utils.DEFAULT_RUNID,
|
||||
utils.COST: 10.0,
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := dspStsRPC.Call(utils.StatSv1ProcessEvent, args, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(reply, expected) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", expected, reply)
|
||||
}
|
||||
|
||||
expectedMetrics = map[string]string{
|
||||
utils.MetaTCC: "133",
|
||||
utils.MetaTCD: "3m0s",
|
||||
}
|
||||
if err := dspStsRPC.Call(utils.StatSv1GetQueueStringMetrics,
|
||||
args2, &metrics); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expectedMetrics, metrics) {
|
||||
t.Errorf("expecting: %+v, received reply: %s", expectedMetrics, metrics)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspStsKillEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
297
dispatcher/suppliers_it_test.go
Executable file
297
dispatcher/suppliers_it_test.go
Executable file
@@ -0,0 +1,297 @@
|
||||
// +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 dispatcher
|
||||
|
||||
import (
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
dspSupCfgPath string
|
||||
dspSupCfg *config.CGRConfig
|
||||
dspSupRPC *rpc.Client
|
||||
instSupCfgPath string
|
||||
instSupCfg *config.CGRConfig
|
||||
instSupRPC *rpc.Client
|
||||
)
|
||||
|
||||
var sTestsDspSup = []func(t *testing.T){
|
||||
testDspSupInitCfg,
|
||||
testDspSupInitDataDb,
|
||||
testDspSupResetStorDb,
|
||||
testDspSupStartEngine,
|
||||
testDspSupRPCConn,
|
||||
testDspSupPing,
|
||||
testDspSupLoadData,
|
||||
testDspSupAddAttributesWithPermision,
|
||||
testDspSupTestAuthKey,
|
||||
testDspSupAddAttributesWithPermision2,
|
||||
testDspSupTestAuthKey2,
|
||||
testDspSupKillEngine,
|
||||
}
|
||||
|
||||
//Test start here
|
||||
func TestDspSupplierS(t *testing.T) {
|
||||
for _, stest := range sTestsDspSup {
|
||||
t.Run("", stest)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspSupInitCfg(t *testing.T) {
|
||||
var err error
|
||||
dspSupCfgPath = path.Join(dspDataDir, "conf", "samples", "dispatcher")
|
||||
dspSupCfg, err = config.NewCGRConfigFromFolder(dspSupCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
dspSupCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(dspSupCfg)
|
||||
instSupCfgPath = path.Join(dspDataDir, "conf", "samples", "tutmysql")
|
||||
instSupCfg, err = config.NewCGRConfigFromFolder(instSupCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
instSupCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(instSupCfg)
|
||||
}
|
||||
|
||||
func testDspSupInitDataDb(t *testing.T) {
|
||||
if err := engine.InitDataDb(instSupCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe out the cdr database
|
||||
func testDspSupResetStorDb(t *testing.T) {
|
||||
if err := engine.InitStorDb(instSupCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Start CGR Engine
|
||||
func testDspSupStartEngine(t *testing.T) {
|
||||
if _, err := engine.StartEngine(instSupCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := engine.StartEngine(dspSupCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Connect rpc client to rater
|
||||
func testDspSupRPCConn(t *testing.T) {
|
||||
var err error
|
||||
instSupRPC, err = jsonrpc.Dial("tcp", instSupCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dspSupRPC, err = jsonrpc.Dial("tcp", dspSupCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func testDspSupPing(t *testing.T) {
|
||||
var reply string
|
||||
if err := instSupRPC.Call(utils.SupplierSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
if err := dspSupRPC.Call(utils.SupplierSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspSupLoadData(t *testing.T) {
|
||||
var reply string
|
||||
attrs := &utils.AttrLoadTpFromFolder{
|
||||
FolderPath: path.Join(dspDataDir, "tariffplans", "tutorial2")}
|
||||
if err := instSupRPC.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
|
||||
func testDspSupAddAttributesWithPermision(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "ThresholdSv1.GetThresholdsForEvent",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var result string
|
||||
if err := instSupRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instSupRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspSupTestAuthKey(t *testing.T) {
|
||||
var rpl *engine.SortedSuppliers
|
||||
args := &ArgsGetSuppliersWithApiKey{
|
||||
APIKey: "12345",
|
||||
ArgsGetSuppliers: engine.ArgsGetSuppliers{
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Time: &nowTime,
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1002",
|
||||
utils.Subject: "1002",
|
||||
utils.Destination: "1001",
|
||||
utils.SetupTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC),
|
||||
utils.Usage: "1m20s",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := dspSupRPC.Call(utils.SupplierSv1GetSuppliers,
|
||||
args, &rpl); err.Error() != utils.ErrUnauthorizedApi.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspSupAddAttributesWithPermision2(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "ThresholdSv1.ProcessEvent;SupplierSv1.GetSuppliers",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var result string
|
||||
if err := instSupRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instSupRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspSupTestAuthKey2(t *testing.T) {
|
||||
var rpl *engine.SortedSuppliers
|
||||
eRpl := &engine.SortedSuppliers{
|
||||
ProfileID: "SPL_LEASTCOST_1",
|
||||
Sorting: utils.MetaLeastCost,
|
||||
SortedSuppliers: []*engine.SortedSupplier{
|
||||
&engine.SortedSupplier{
|
||||
SupplierID: "supplier2",
|
||||
SupplierParameters: "",
|
||||
SortingData: map[string]interface{}{
|
||||
utils.Cost: 0.1166,
|
||||
utils.RatingPlanID: "RP_1002_LOW",
|
||||
utils.Weight: 10.0,
|
||||
},
|
||||
},
|
||||
&engine.SortedSupplier{
|
||||
SupplierID: "supplier1",
|
||||
SupplierParameters: "",
|
||||
SortingData: map[string]interface{}{
|
||||
utils.Cost: 0.2334,
|
||||
utils.RatingPlanID: "RP_1002",
|
||||
utils.Weight: 10.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
args := &ArgsGetSuppliersWithApiKey{
|
||||
APIKey: "12345",
|
||||
ArgsGetSuppliers: engine.ArgsGetSuppliers{
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Time: &nowTime,
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1002",
|
||||
utils.Subject: "1002",
|
||||
utils.Destination: "1001",
|
||||
utils.SetupTime: time.Date(2017, 12, 1, 14, 25, 0, 0, time.UTC),
|
||||
utils.Usage: "1m20s",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := dspSupRPC.Call(utils.SupplierSv1GetSuppliers,
|
||||
args, &rpl); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eRpl, rpl) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(eRpl), utils.ToJSON(rpl))
|
||||
}
|
||||
}
|
||||
|
||||
func testDspSupKillEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ package dispatcher
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
@@ -35,38 +36,8 @@ func (dS *DispatcherService) ThresholdSv1Ping(ign string, reply *string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/* To be implemented (+console)
|
||||
func (dS *DispatcherService) ThresholdSv1GetThresholdIDs(tenant string, tIDs *[]string) (err error) {
|
||||
if dS.thdS == nil {
|
||||
return utils.NewErrNotConnected(utils.ThresholdS)
|
||||
}
|
||||
ev := &utils.CGREvent{
|
||||
Tenant: args.Tenant,
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Context: utils.StringPointer(utils.MetaAuth),
|
||||
Time: args.ArgRSv1ResourceUsage.Time,
|
||||
Event: map[string]interface{}{
|
||||
utils.APIKey: args.APIKey,
|
||||
},
|
||||
}
|
||||
var rplyEv engine.AttrSProcessEventReply
|
||||
if err = dS.authorizeEvent(ev, &rplyEv); err != nil {
|
||||
return
|
||||
}
|
||||
mp := utils.ParseStringMap(rplyEv.CGREvent.Event[utils.APIMethods])
|
||||
if !mp.HasKey(utils.ResourceSv1GetResourcesForEvent) {
|
||||
return utils.ErrUnauthorizedApi
|
||||
}
|
||||
if err = dS.thdS.Call(utils.ThresholdSv1GetThresholdIDs, tenant, tIDs); err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<DispatcherS> error: %s ThresholdS.", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
func (dS *DispatcherService) ThresholdSv1GetThresholdForEvent(args *ArgsProcessEventWithApiKey,
|
||||
t *engine.Threshold) (err error) {
|
||||
func (dS *DispatcherService) ThresholdSv1GetThresholdsForEvent(args *ArgsProcessEventWithApiKey,
|
||||
t *engine.Thresholds) (err error) {
|
||||
if dS.thdS == nil {
|
||||
return utils.NewErrNotConnected(utils.ThresholdS)
|
||||
}
|
||||
@@ -74,6 +45,7 @@ func (dS *DispatcherService) ThresholdSv1GetThresholdForEvent(args *ArgsProcessE
|
||||
Tenant: args.Tenant,
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Context: utils.StringPointer(utils.MetaAuth),
|
||||
Time: utils.TimePointer(time.Now()),
|
||||
Event: map[string]interface{}{
|
||||
utils.APIKey: args.APIKey,
|
||||
},
|
||||
@@ -89,7 +61,7 @@ func (dS *DispatcherService) ThresholdSv1GetThresholdForEvent(args *ArgsProcessE
|
||||
if !utils.ParseStringMap(apiMethods).HasKey(utils.ThresholdSv1GetThresholdsForEvent) {
|
||||
return utils.ErrUnauthorizedApi
|
||||
}
|
||||
return dS.thdS.Call(utils.ThresholdSv1GetThresholdsForEvent, args.TenantID, t)
|
||||
return dS.thdS.Call(utils.ThresholdSv1GetThresholdsForEvent, args.ArgsProcessEvent, t)
|
||||
}
|
||||
|
||||
func (dS *DispatcherService) ThresholdSv1ProcessEvent(args *ArgsProcessEventWithApiKey,
|
||||
@@ -101,6 +73,7 @@ func (dS *DispatcherService) ThresholdSv1ProcessEvent(args *ArgsProcessEventWith
|
||||
Tenant: args.Tenant,
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Context: utils.StringPointer(utils.MetaAuth),
|
||||
Time: utils.TimePointer(time.Now()),
|
||||
Event: map[string]interface{}{
|
||||
utils.APIKey: args.APIKey,
|
||||
},
|
||||
@@ -117,5 +90,4 @@ func (dS *DispatcherService) ThresholdSv1ProcessEvent(args *ArgsProcessEventWith
|
||||
return utils.ErrUnauthorizedApi
|
||||
}
|
||||
return dS.thdS.Call(utils.ThresholdSv1ProcessEvent, args.ArgsProcessEvent, tIDs)
|
||||
|
||||
}
|
||||
|
||||
296
dispatcher/thresholds_it_test.go
Executable file
296
dispatcher/thresholds_it_test.go
Executable file
@@ -0,0 +1,296 @@
|
||||
// +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 dispatcher
|
||||
|
||||
import (
|
||||
"net/rpc"
|
||||
"net/rpc/jsonrpc"
|
||||
"path"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
dspThCfgPath string
|
||||
dspThCfg *config.CGRConfig
|
||||
dspThRPC *rpc.Client
|
||||
instThCfgPath string
|
||||
instThCfg *config.CGRConfig
|
||||
instThRPC *rpc.Client
|
||||
)
|
||||
|
||||
var sTestsDspTh = []func(t *testing.T){
|
||||
testDspThInitCfg,
|
||||
testDspThInitDataDb,
|
||||
testDspThResetStorDb,
|
||||
testDspThStartEngine,
|
||||
testDspThRPCConn,
|
||||
testDspThPing,
|
||||
testDspThLoadData,
|
||||
testDspThAddAttributesWithPermision,
|
||||
testDspThTestAuthKey,
|
||||
testDspThAddAttributesWithPermision2,
|
||||
testDspThTestAuthKey2,
|
||||
testDspThKillEngine,
|
||||
}
|
||||
|
||||
//Test start here
|
||||
func TestDspThresholdS(t *testing.T) {
|
||||
for _, stest := range sTestsDspTh {
|
||||
t.Run("", stest)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspThInitCfg(t *testing.T) {
|
||||
var err error
|
||||
dspThCfgPath = path.Join(dspDataDir, "conf", "samples", "dispatcher")
|
||||
dspThCfg, err = config.NewCGRConfigFromFolder(dspThCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
dspThCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(dspThCfg)
|
||||
instThCfgPath = path.Join(dspDataDir, "conf", "samples", "tutmysql")
|
||||
instThCfg, err = config.NewCGRConfigFromFolder(instThCfgPath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
instThCfg.DataFolderPath = dspDataDir // Share DataFolderPath through config towards StoreDb for Flush()
|
||||
config.SetCgrConfig(instThCfg)
|
||||
}
|
||||
|
||||
func testDspThInitDataDb(t *testing.T) {
|
||||
if err := engine.InitDataDb(instThCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe out the cdr database
|
||||
func testDspThResetStorDb(t *testing.T) {
|
||||
if err := engine.InitStorDb(instThCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Start CGR Engine
|
||||
func testDspThStartEngine(t *testing.T) {
|
||||
if _, err := engine.StartEngine(instThCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := engine.StartEngine(dspThCfgPath, dspDelay); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Connect rpc client to rater
|
||||
func testDspThRPCConn(t *testing.T) {
|
||||
var err error
|
||||
instThRPC, err = jsonrpc.Dial("tcp", instThCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dspThRPC, err = jsonrpc.Dial("tcp", dspThCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspThPing(t *testing.T) {
|
||||
var reply string
|
||||
if err := instThRPC.Call(utils.ThresholdSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
if err := dspThRPC.Call(utils.ThresholdSv1Ping, "", &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.Pong {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspThLoadData(t *testing.T) {
|
||||
var reply string
|
||||
attrs := &utils.AttrLoadTpFromFolder{
|
||||
FolderPath: path.Join(dspDataDir, "tariffplans", "tutorial2")}
|
||||
if err := instThRPC.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
|
||||
func testDspThAddAttributesWithPermision(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "ThresholdSv1.GetThresholdsForEvent",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var result string
|
||||
if err := instThRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instThRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspThTestAuthKey(t *testing.T) {
|
||||
var ids []string
|
||||
nowTime := time.Now()
|
||||
args := &ArgsProcessEventWithApiKey{
|
||||
APIKey: "12345",
|
||||
ArgsProcessEvent: engine.ArgsProcessEvent{
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Time: &nowTime,
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1002"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := dspThRPC.Call(utils.ThresholdSv1ProcessEvent,
|
||||
args, &ids); err.Error() != utils.ErrUnauthorizedApi.Error() {
|
||||
t.Error(err)
|
||||
}
|
||||
var th *engine.Thresholds
|
||||
eTh := &engine.Thresholds{
|
||||
&engine.Threshold{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "THD_ACNT_1002",
|
||||
Hits: 0,
|
||||
},
|
||||
}
|
||||
if err := dspThRPC.Call(utils.ThresholdSv1GetThresholdsForEvent, args, &th); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eTh, th) {
|
||||
t.Errorf("expecting: %+v, received: %+v", eTh, th)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspThAddAttributesWithPermision2(t *testing.T) {
|
||||
alsPrf := &engine.AttributeProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "AuthKey",
|
||||
Contexts: []string{utils.MetaAuth},
|
||||
FilterIDs: []string{"*string:APIKey:12345"},
|
||||
ActivationInterval: &utils.ActivationInterval{
|
||||
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
|
||||
},
|
||||
Attributes: []*engine.Attribute{
|
||||
&engine.Attribute{
|
||||
FieldName: utils.APIMethods,
|
||||
Initial: utils.META_ANY,
|
||||
Substitute: "ThresholdSv1.ProcessEvent;ThresholdSv1.GetThresholdsForEvent",
|
||||
Append: true,
|
||||
},
|
||||
},
|
||||
Weight: 20,
|
||||
}
|
||||
var result string
|
||||
if err := instThRPC.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if result != utils.OK {
|
||||
t.Error("Unexpected reply returned", result)
|
||||
}
|
||||
var reply *engine.AttributeProfile
|
||||
if err := instThRPC.Call("ApierV1.GetAttributeProfile",
|
||||
&utils.TenantID{Tenant: "cgrates.org", ID: "AuthKey"}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(alsPrf, reply) {
|
||||
t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspThTestAuthKey2(t *testing.T) {
|
||||
var ids []string
|
||||
eIDs := []string{"THD_ACNT_1002"}
|
||||
nowTime := time.Now()
|
||||
args := &ArgsProcessEventWithApiKey{
|
||||
APIKey: "12345",
|
||||
ArgsProcessEvent: engine.ArgsProcessEvent{
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: utils.UUIDSha1Prefix(),
|
||||
Time: &nowTime,
|
||||
Event: map[string]interface{}{
|
||||
utils.Account: "1002"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := dspThRPC.Call(utils.ThresholdSv1ProcessEvent, args, &ids); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eIDs, ids) {
|
||||
t.Errorf("expecting: %+v, received: %+v", eIDs, ids)
|
||||
}
|
||||
var th *engine.Thresholds
|
||||
eTh := &engine.Thresholds{
|
||||
&engine.Threshold{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "THD_ACNT_1002",
|
||||
Hits: 1,
|
||||
},
|
||||
}
|
||||
if err := dspThRPC.Call(utils.ThresholdSv1GetThresholdsForEvent, args, &th); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual((*eTh)[0].Tenant, (*th)[0].Tenant) {
|
||||
t.Errorf("expecting: %+v, received: %+v", (*eTh)[0].Tenant, (*th)[0].Tenant)
|
||||
} else if !reflect.DeepEqual((*eTh)[0].ID, (*th)[0].ID) {
|
||||
t.Errorf("expecting: %+v, received: %+v", (*eTh)[0].ID, (*th)[0].ID)
|
||||
} else if !reflect.DeepEqual((*eTh)[0].Hits, (*th)[0].Hits) {
|
||||
t.Errorf("expecting: %+v, received: %+v", (*eTh)[0].Hits, (*th)[0].Hits)
|
||||
}
|
||||
}
|
||||
|
||||
func testDspThKillEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := engine.KillEngine(dspDelay); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
@@ -19,11 +19,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package dispatcher
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var ( //var used in all tests
|
||||
dspDelay = 1000
|
||||
dspDataDir = "/usr/share/cgrates"
|
||||
nowTime = time.Now()
|
||||
)
|
||||
|
||||
type CGREvWithApiKey struct {
|
||||
APIKey string
|
||||
utils.CGREvent
|
||||
|
||||
Reference in New Issue
Block a user