mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Completing Diameter DryRun integration test
This commit is contained in:
@@ -46,7 +46,7 @@ var dmtClient *DiameterClient
|
||||
|
||||
var rplyTimeout time.Duration
|
||||
|
||||
func TestDiamITInitCfg(t *testing.T) {
|
||||
func TestDiamItInitCfg(t *testing.T) {
|
||||
daCfgPath = path.Join(*dataDir, "conf", "samples", "diamagent")
|
||||
// Init config first
|
||||
var err error
|
||||
@@ -60,14 +60,14 @@ func TestDiamITInitCfg(t *testing.T) {
|
||||
}
|
||||
|
||||
// Remove data in both rating and accounting db
|
||||
func TestDiamITResetDataDb(t *testing.T) {
|
||||
func TestDiamItResetDataDb(t *testing.T) {
|
||||
if err := engine.InitDataDb(daCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe out the cdr database
|
||||
func TestDiamITResetStorDb(t *testing.T) {
|
||||
func TestDiamItResetStorDb(t *testing.T) {
|
||||
if err := engine.InitStorDb(daCfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -75,14 +75,14 @@ func TestDiamITResetStorDb(t *testing.T) {
|
||||
|
||||
/*
|
||||
// Start CGR Engine
|
||||
func TestDiamITStartEngine(t *testing.T) {
|
||||
func TestDiamItStartEngine(t *testing.T) {
|
||||
if _, err := engine.StopStartEngine(daCfgPath, 4000); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func TestDiamITConnectDiameterClient(t *testing.T) {
|
||||
func TestDiamItConnectDiameterClient(t *testing.T) {
|
||||
dmtClient, err = NewDiameterClient(daCfg.DiameterAgentCfg().Listen, "INTEGRATION_TESTS",
|
||||
daCfg.DiameterAgentCfg().OriginRealm,
|
||||
daCfg.DiameterAgentCfg().VendorId, daCfg.DiameterAgentCfg().ProductName,
|
||||
@@ -93,7 +93,7 @@ func TestDiamITConnectDiameterClient(t *testing.T) {
|
||||
}
|
||||
|
||||
// Connect rpc client to rater
|
||||
func TestDiamITApierRpcConn(t *testing.T) {
|
||||
func TestDiamItApierRpcConn(t *testing.T) {
|
||||
var err error
|
||||
apierRpc, err = jsonrpc.Dial("tcp", daCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
|
||||
if err != nil {
|
||||
@@ -102,7 +102,7 @@ func TestDiamITApierRpcConn(t *testing.T) {
|
||||
}
|
||||
|
||||
// Load the tariff plan, creating accounts and their balances
|
||||
func TestDiamITTPFromFolder(t *testing.T) {
|
||||
func TestDiamItTPFromFolder(t *testing.T) {
|
||||
attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "oldtutorial")}
|
||||
var loadInst utils.LoadInstance
|
||||
if err := apierRpc.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &loadInst); err != nil {
|
||||
@@ -111,7 +111,7 @@ func TestDiamITTPFromFolder(t *testing.T) {
|
||||
time.Sleep(time.Duration(1000) * time.Millisecond) // Give time for scheduler to execute topups
|
||||
}
|
||||
|
||||
func TestDiamITDryRun(t *testing.T) {
|
||||
func TestDiamItDryRun(t *testing.T) {
|
||||
ccr := diam.NewRequest(diam.CreditControl, 4, nil)
|
||||
ccr.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("cgrates;1451911932;00082"))
|
||||
ccr.NewAVP(avp.OriginHost, avp.Mbit, 0, datatype.DiameterIdentity("CGR-DA"))
|
||||
@@ -120,7 +120,7 @@ func TestDiamITDryRun(t *testing.T) {
|
||||
ccr.NewAVP(avp.DestinationHost, avp.Mbit, 0, datatype.DiameterIdentity("CGR-DA"))
|
||||
ccr.NewAVP(avp.UserName, avp.Mbit, 0, datatype.UTF8String("CGR-DA"))
|
||||
ccr.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(4))
|
||||
ccr.NewAVP(avp.ServiceContextID, avp.Mbit, 0, datatype.UTF8String("TestDiamITDryRun")) // Match specific DryRun profile
|
||||
ccr.NewAVP(avp.ServiceContextID, avp.Mbit, 0, datatype.UTF8String("TestDiamItDryRun")) // Match specific DryRun profile
|
||||
ccr.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(1))
|
||||
ccr.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(1))
|
||||
ccr.NewAVP(avp.EventTimestamp, avp.Mbit, 0, datatype.Time(time.Date(2016, 1, 5, 11, 30, 10, 0, time.UTC)))
|
||||
@@ -169,15 +169,73 @@ func TestDiamITDryRun(t *testing.T) {
|
||||
if msg == nil {
|
||||
t.Fatal("No message returned")
|
||||
}
|
||||
avps, err := msg.FindAVPsWithPath([]interface{}{"Result-Code"}, dict.UndefinedVendorID)
|
||||
if err != nil {
|
||||
// Result-Code
|
||||
eVal := "2002"
|
||||
if avps, err := msg.FindAVPsWithPath([]interface{}{"Result-Code"}, dict.UndefinedVendorID); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(avps) == 0 {
|
||||
t.Error("Missing AVP")
|
||||
} else if val, err := diamAVPAsString(avps[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if val != eVal {
|
||||
t.Errorf("expecting: %s, received: <%s>", eVal, val)
|
||||
}
|
||||
if len(avps) == 0 {
|
||||
t.Error("Result-Code")
|
||||
eVal = "cgrates;1451911932;00082"
|
||||
if avps, err := msg.FindAVPsWithPath([]interface{}{"Session-Id"}, dict.UndefinedVendorID); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(avps) == 0 {
|
||||
t.Error("Missing AVP")
|
||||
} else if val, err := diamAVPAsString(avps[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if val != eVal {
|
||||
t.Errorf("expecting: %s, received: <%s>", eVal, val)
|
||||
}
|
||||
eVal := "300"
|
||||
if val, err := diamAVPAsString(avps[0]); err != nil {
|
||||
eVal = "CGR-DA"
|
||||
if avps, err := msg.FindAVPsWithPath([]interface{}{"Origin-Host"}, dict.UndefinedVendorID); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(avps) == 0 {
|
||||
t.Error("Missing AVP")
|
||||
} else if val, err := diamAVPAsString(avps[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if val != eVal {
|
||||
t.Errorf("expecting: %s, received: <%s>", eVal, val)
|
||||
}
|
||||
eVal = "cgrates.org"
|
||||
if avps, err := msg.FindAVPsWithPath([]interface{}{"Origin-Realm"}, dict.UndefinedVendorID); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(avps) == 0 {
|
||||
t.Error("Missing AVP")
|
||||
} else if val, err := diamAVPAsString(avps[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if val != eVal {
|
||||
t.Errorf("expecting: %s, received: <%s>", eVal, val)
|
||||
}
|
||||
eVal = "4"
|
||||
if avps, err := msg.FindAVPsWithPath([]interface{}{"Auth-Application-Id"}, dict.UndefinedVendorID); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(avps) == 0 {
|
||||
t.Error("Missing AVP")
|
||||
} else if val, err := diamAVPAsString(avps[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if val != eVal {
|
||||
t.Errorf("expecting: %s, received: <%s>", eVal, val)
|
||||
}
|
||||
eVal = "1"
|
||||
if avps, err := msg.FindAVPsWithPath([]interface{}{"CC-Request-Type"}, dict.UndefinedVendorID); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(avps) == 0 {
|
||||
t.Error("Missing AVP")
|
||||
} else if val, err := diamAVPAsString(avps[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if val != eVal {
|
||||
t.Errorf("expecting: %s, received: <%s>", eVal, val)
|
||||
}
|
||||
eVal = "1"
|
||||
if avps, err := msg.FindAVPsWithPath([]interface{}{"CC-Request-Number"}, dict.UndefinedVendorID); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(avps) == 0 {
|
||||
t.Error("Missing AVP")
|
||||
} else if val, err := diamAVPAsString(avps[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if val != eVal {
|
||||
t.Errorf("expecting: %s, received: <%s>", eVal, val)
|
||||
|
||||
@@ -147,7 +147,6 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) {
|
||||
writeOnConn(c, m.Answer(diam.UnableToComply))
|
||||
return
|
||||
}
|
||||
fmt.Printf("After processing successfully the message, have reply: %+v\n", rply)
|
||||
a := m.Answer(diam.Success)
|
||||
// write reply into message
|
||||
for _, val := range rply.Values() {
|
||||
@@ -179,12 +178,12 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) {
|
||||
writeOnConn(c, m.Answer(diam.UnableToComply))
|
||||
return
|
||||
}
|
||||
var apnd bool
|
||||
if itm.Config == nil || !itm.Config.NewBranch {
|
||||
apnd = true
|
||||
var newBranch bool
|
||||
if itm.Config != nil && itm.Config.NewBranch {
|
||||
newBranch = true
|
||||
}
|
||||
if err := messageSetAVPsWithPath(a, itm.Path,
|
||||
itmStr, apnd, da.cgrCfg.DefaultTimezone); err != nil {
|
||||
itmStr, newBranch, da.cgrCfg.DefaultTimezone); err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> error: %s setting reply item: %s for message: %s",
|
||||
utils.DiameterAgent, err.Error(), utils.ToJSON(itm), m))
|
||||
|
||||
@@ -194,7 +194,7 @@ func newDiamDataType(typ datatype.TypeID, valStr,
|
||||
// messageAddAVPsWithPath will dynamically add AVPs into the message
|
||||
// append: append to the message, on false overwrite if AVP is single or add to group if AVP is Grouped
|
||||
func messageSetAVPsWithPath(m *diam.Message, pathStr []string,
|
||||
avpValStr string, appnd bool, tmz string) (err error) {
|
||||
avpValStr string, newBranch bool, tmz string) (err error) {
|
||||
if len(pathStr) == 0 {
|
||||
return errors.New("empty path as AVP filter")
|
||||
}
|
||||
@@ -209,11 +209,11 @@ func messageSetAVPsWithPath(m *diam.Message, pathStr []string,
|
||||
dictAVPs[i] = dictAVP
|
||||
}
|
||||
}
|
||||
if dictAVPs[len(path)-1].Data.Type == diam.GroupedAVPType {
|
||||
lastAVPIdx := len(path) - 1
|
||||
if dictAVPs[lastAVPIdx].Data.Type == diam.GroupedAVPType {
|
||||
return errors.New("last AVP in path cannot be GroupedAVP")
|
||||
}
|
||||
var msgAVP *diam.AVP // Keep a reference here towards last AVP
|
||||
lastAVPIdx := len(path) - 1
|
||||
for i := lastAVPIdx; i >= 0; i-- {
|
||||
var typeVal datatype.Type
|
||||
if i == lastAVPIdx {
|
||||
@@ -225,7 +225,7 @@ func messageSetAVPsWithPath(m *diam.Message, pathStr []string,
|
||||
AVP: []*diam.AVP{msgAVP}}
|
||||
}
|
||||
newMsgAVP := diam.NewAVP(dictAVPs[i].Code, avp.Mbit, dictAVPs[i].VendorID, typeVal) // FixMe: maybe Mbit with dictionary one
|
||||
if i == lastAVPIdx-1 && !appnd { // last AVP needs to be appended in group
|
||||
if i == lastAVPIdx-1 && !newBranch {
|
||||
avps, err := m.FindAVPsWithPath(path[:lastAVPIdx], dict.UndefinedVendorID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -239,7 +239,7 @@ func messageSetAVPsWithPath(m *diam.Message, pathStr []string,
|
||||
}
|
||||
msgAVP = newMsgAVP
|
||||
}
|
||||
if !appnd { // Not group AVP, replace the previous set one with this one
|
||||
if !newBranch { // Not group AVP, replace the previous set one with this one
|
||||
avps, err := m.FindAVPsWithPath(path, dict.UndefinedVendorID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -302,11 +302,14 @@ func (dP *diameterDP) FieldAsString(fldPath []string) (data string, err error) {
|
||||
|
||||
// FieldAsInterface is part of engine.DataProvider interface
|
||||
func (dP *diameterDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
|
||||
if data, err = dP.cache.FieldAsInterface(fldPath); err == nil ||
|
||||
err != utils.ErrNotFound { // item found in cache
|
||||
return nil, err
|
||||
if data, err = dP.cache.FieldAsInterface(fldPath); err != nil {
|
||||
if err != utils.ErrNotFound { // item found in cache
|
||||
return nil, err
|
||||
}
|
||||
err = nil // cancel previous err
|
||||
} else {
|
||||
return // data was found in cache
|
||||
}
|
||||
err = nil // cancel previous err
|
||||
// lastPath can contain selector inside
|
||||
lastPath := fldPath[len(fldPath)-1]
|
||||
var slctrStr string
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package agents
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/fiorix/go-diameter/diam"
|
||||
@@ -103,3 +104,76 @@ func TestDPFieldAsInterface(t *testing.T) {
|
||||
t.Errorf("Expecting: %v, received: %v", eOut, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessageSetAVPsWithPath(t *testing.T) {
|
||||
eMessage := diam.NewRequest(diam.CreditControl, 4, nil)
|
||||
eMessage.NewAVP("Session-Id", avp.Mbit, 0,
|
||||
datatype.UTF8String("simuhuawei;1449573472;00001"))
|
||||
m := diam.NewMessage(diam.CreditControl, diam.RequestFlag, 4,
|
||||
eMessage.Header.HopByHopID, eMessage.Header.EndToEndID, nil)
|
||||
if err := messageSetAVPsWithPath(m,
|
||||
[]string{"Session-Id"}, "simuhuawei;1449573472;00001",
|
||||
false, "UTC"); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eMessage, m) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eMessage, m)
|
||||
}
|
||||
// create same attribute twice
|
||||
eMessage.NewAVP("Session-Id", avp.Mbit, 0,
|
||||
datatype.UTF8String("simuhuawei;1449573472;00002"))
|
||||
if err := messageSetAVPsWithPath(m,
|
||||
[]string{"Session-Id"}, "simuhuawei;1449573472;00002",
|
||||
true, "UTC"); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eMessage.AVP, m.AVP) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eMessage, m)
|
||||
}
|
||||
// overwrite of previous attribute
|
||||
eMessage = diam.NewRequest(diam.CreditControl, 4, nil)
|
||||
eMessage.NewAVP("Session-Id", avp.Mbit, 0,
|
||||
datatype.UTF8String("simuhuawei;1449573472;00001"))
|
||||
eMessage.NewAVP("Session-Id", avp.Mbit, 0,
|
||||
datatype.UTF8String("simuhuawei;1449573472;00003"))
|
||||
if err := messageSetAVPsWithPath(m,
|
||||
[]string{"Session-Id"}, "simuhuawei;1449573472;00003",
|
||||
false, "UTC"); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eMessage.AVP, m.AVP) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eMessage, m)
|
||||
}
|
||||
// adding a groupped AVP
|
||||
eMessage.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(avp.SubscriptionIDType, avp.Mbit, 0, datatype.Enumerated(0)),
|
||||
diam.NewAVP(avp.SubscriptionIDData, avp.Mbit, 0, datatype.UTF8String("1001")),
|
||||
}})
|
||||
if err := messageSetAVPsWithPath(m,
|
||||
[]string{"Subscription-Id", "Subscription-Id-Type"}, "0",
|
||||
false, "UTC"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := messageSetAVPsWithPath(m,
|
||||
[]string{"Subscription-Id", "Subscription-Id-Data"}, "1001",
|
||||
false, "UTC"); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(eMessage.AVP) != len(m.AVP) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eMessage, m)
|
||||
}
|
||||
eMessage.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(avp.SubscriptionIDType, avp.Mbit, 0, datatype.Enumerated(1)),
|
||||
diam.NewAVP(avp.SubscriptionIDData, avp.Mbit, 0, datatype.UTF8String("1002")),
|
||||
}})
|
||||
if err := messageSetAVPsWithPath(m,
|
||||
[]string{"Subscription-Id", "Subscription-Id-Type"}, "1",
|
||||
true, "UTC"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := messageSetAVPsWithPath(m,
|
||||
[]string{"Subscription-Id", "Subscription-Id-Data"}, "1002",
|
||||
false, "UTC"); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(eMessage.AVP) != len(m.AVP) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eMessage, m)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,11 +62,14 @@ func (hU *httpUrlDP) FieldAsInterface(fldPath []string) (data interface{}, err e
|
||||
if len(fldPath) != 1 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
if data, err = hU.cache.FieldAsInterface(fldPath); err == nil ||
|
||||
err != utils.ErrNotFound { // item found in cache
|
||||
return
|
||||
if data, err = hU.cache.FieldAsInterface(fldPath); err != nil {
|
||||
if err != utils.ErrNotFound { // item found in cache
|
||||
return
|
||||
}
|
||||
err = nil // cancel previous err
|
||||
} else {
|
||||
return // data found in cache
|
||||
}
|
||||
err = nil // cancel previous err
|
||||
data = hU.req.FormValue(fldPath[0])
|
||||
hU.cache.Set(fldPath, data, false)
|
||||
return
|
||||
|
||||
@@ -158,11 +158,14 @@ func (pk *radiusDP) FieldAsInterface(fldPath []string) (data interface{}, err er
|
||||
if len(fldPath) != 1 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
if data, err = pk.cache.FieldAsInterface(fldPath); err == nil ||
|
||||
err != utils.ErrNotFound { // item found in cache
|
||||
return
|
||||
if data, err = pk.cache.FieldAsInterface(fldPath); err != nil {
|
||||
if err != utils.ErrNotFound { // item found in cache
|
||||
return
|
||||
}
|
||||
err = nil // cancel previous err
|
||||
} else {
|
||||
return // data found in cache
|
||||
}
|
||||
err = nil // cancel previous err
|
||||
if len(pk.req.AttributesWithName(fldPath[0], "")) != 0 {
|
||||
data = pk.req.AttributesWithName(fldPath[0], "")[0].GetStringValue()
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{
|
||||
"id": "dryrun1",
|
||||
"filters": ["*string:*vars.*cmd:CCR", "*string:*req.Service-Context-Id:TestDiamITDryRun"],
|
||||
"filters": ["*string:*vars.*cmd:CCR", "*string:*req.Service-Context-Id:TestDiamItDryRun"],
|
||||
"flags": ["*dryrun"],
|
||||
"request_fields":[
|
||||
{"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*sms"},
|
||||
@@ -16,7 +16,7 @@
|
||||
],
|
||||
"reply_fields":[
|
||||
{"tag": "CCATemplate", "type": "*template", "value": "*cca"},
|
||||
{"tag": "ResultCode", "field_id": "Result-Code", "type": "*constant", "value": "300"},
|
||||
{"tag": "ResultCode", "field_id": "Result-Code", "type": "*constant", "value": "2002"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user