mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Adding Apier tests for cdrserver, newly added commands for account triggers and account timings
This commit is contained in:
@@ -26,7 +26,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type AttrAcntActionTimings struct {
|
||||
type AttrAcntAction struct {
|
||||
Tenant string
|
||||
Account string
|
||||
Direction string
|
||||
@@ -45,7 +45,7 @@ type AccountActionTiming struct {
|
||||
NextExecTime time.Time // Next execution time
|
||||
}
|
||||
|
||||
func (self *ApierV1) GetAccountActionTimings(attrs AttrAcntActionTimings, reply *[]*AccountActionTiming) error {
|
||||
func (self *ApierV1) GetAccountActionTimings(attrs AttrAcntAction, reply *[]*AccountActionTiming) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account", "Direction"}); len(missing) != 0 {
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
@@ -109,7 +109,7 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) e
|
||||
}
|
||||
|
||||
// Returns a list of ActionTriggers on an account
|
||||
func (self *ApierV1) GetAccountActionTriggers(attrs AttrAcntActionTimings, reply *engine.ActionTriggerPriotityList) error {
|
||||
func (self *ApierV1) GetAccountActionTriggers(attrs AttrAcntAction, reply *engine.ActionTriggerPriotityList) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account", "Direction"}); len(missing) != 0 {
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ToDo: Replace rpc.Client with internal rpc server and Apier using internal map as both data and stor so we can run the tests non-local
|
||||
@@ -119,7 +122,7 @@ func TestStartEngine(t *testing.T) {
|
||||
t.Fatal("Cannot find cgr-engine executable")
|
||||
}
|
||||
exec.Command("pkill", "cgr-engine").Run() // Just to make sure another one is not running, bit brutal maybe we can fine tune it
|
||||
engine := exec.Command(enginePath, "-rater", "-scheduler", "-config", path.Join(*dataDir, "conf", "cgrates.cfg"))
|
||||
engine := exec.Command(enginePath, "-rater", "-scheduler", "-cdrs", "-mediator", "-config", path.Join(*dataDir, "conf", "cgrates.cfg"))
|
||||
if err := engine.Start(); err != nil {
|
||||
t.Fatal("Cannot start cgr-engine: ", err.Error())
|
||||
}
|
||||
@@ -984,23 +987,67 @@ func TestApierAddTriggeredAction(t *testing.T) {
|
||||
*attrs2 = *attrs
|
||||
attrs2.Account = "dan3" // Does not exist so it should error when adding triggers on it
|
||||
// Add trigger to an account which does n exist
|
||||
if err := rater.Call("ApierV1.ExecuteAction", attrs2, &reply2); err == nil || reply2 == "OK" {
|
||||
if err := rater.Call("ApierV1.AddTriggeredAction", attrs2, &reply2); err == nil || reply2 == "OK" {
|
||||
t.Error("Expecting error on ApierV1.AddTriggeredAction.", err, reply2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Test here AddTriggeredAction
|
||||
func TestApierGetAccountActionTriggers(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
var reply engine.ActionTriggerPriotityList
|
||||
req := AttrAcntAction{Tenant: "cgrates.org", Account:"dan2", Direction: "*out"}
|
||||
if err := rater.Call("ApierV1.GetAccountActionTriggers", req, &reply); err != nil {
|
||||
t.Error("Got error on ApierV1.GetAccountActionTimings: ", err.Error())
|
||||
} else if len(reply) != 1 || reply[0].ActionsId != "WARN_VIA_HTTP" {
|
||||
t.Errorf("Unexpected action triggers received %v", reply)
|
||||
}
|
||||
}
|
||||
|
||||
// Test here RemAccountActionTriggers
|
||||
func TestApierRemAccountActionTriggers(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
// Test first get so we can steal the id which we need to remove
|
||||
var reply engine.ActionTriggerPriotityList
|
||||
req := AttrAcntAction{Tenant: "cgrates.org", Account:"dan2", Direction: "*out"}
|
||||
if err := rater.Call("ApierV1.GetAccountActionTriggers", req, &reply); err != nil {
|
||||
t.Error("Got error on ApierV1.GetAccountActionTimings: ", err.Error())
|
||||
} else if len(reply) != 1 || reply[0].ActionsId != "WARN_VIA_HTTP" {
|
||||
t.Errorf("Unexpected action triggers received %v", reply)
|
||||
}
|
||||
var rmReply string
|
||||
rmReq := AttrRemAcntActionTriggers{Tenant: "cgrates.org", Account:"dan2", Direction: "*out", ActionTriggerId: reply[0].Id}
|
||||
if err := rater.Call("ApierV1.RemAccountActionTriggers", rmReq, &rmReply); err != nil {
|
||||
t.Error("Got error on ApierV1.RemActionTiming: ", err.Error())
|
||||
} else if rmReply != OK {
|
||||
t.Error("Unexpected answer received", rmReply)
|
||||
}
|
||||
if err := rater.Call("ApierV1.GetAccountActionTriggers", req, &reply); err != nil {
|
||||
t.Error("Got error on ApierV1.GetAccountActionTriggers: ", err.Error())
|
||||
} else if len(reply) != 0 {
|
||||
t.Errorf("Unexpected action triggers received %v", reply)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test here AddAccount
|
||||
func TestApierAddAccount(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
//reply := ""
|
||||
attrs := &AttrAddAccount{Tenant: "cgrates.org", Direction: "*out", Account: "dan4", Type: "prepaid", ActionTimingsId: "PREPAID_10"}
|
||||
//if err := rater.Call("ApierV1.AddAccount", attrs, &reply); err != nil {
|
||||
// t.Error("Got error on ApierV1.AddAccount: ", err.Error())
|
||||
//} else if reply != "OK" {
|
||||
// t.Errorf("Calling ApierV1.AddAccount received: %s", reply)
|
||||
//}
|
||||
reply := ""
|
||||
attrs := &AttrAddAccount{Tenant: "cgrates.org", Direction: "*out", Account: "dan4", Type: "prepaid", ActionTimingsId: "ATMS_1"}
|
||||
if err := rater.Call("ApierV1.AddAccount", attrs, &reply); err != nil {
|
||||
t.Error("Got error on ApierV1.AddAccount: ", err.Error())
|
||||
} else if reply != "OK" {
|
||||
t.Errorf("Calling ApierV1.AddAccount received: %s", reply)
|
||||
}
|
||||
reply2 := ""
|
||||
attrs2 := new(AttrAddAccount)
|
||||
*attrs2 = *attrs
|
||||
@@ -1011,6 +1058,45 @@ func TestApierAddAccount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test here GetAccountActionTimings
|
||||
func TestApierGetAccountActionTimings(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
var reply []*AccountActionTiming
|
||||
req := AttrAcntAction{Tenant: "cgrates.org", Account:"dan4", Direction: "*out"}
|
||||
if err := rater.Call("ApierV1.GetAccountActionTimings", req, &reply); err != nil {
|
||||
t.Error("Got error on ApierV1.GetAccountActionTimings: ", err.Error())
|
||||
} else if len(reply) != 1 {
|
||||
t.Error("Unexpected action timings received")
|
||||
} else {
|
||||
if reply[0].ActionTimingsId != "ATMS_1" {
|
||||
t.Errorf("Unexpected ActionTImingsId received")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test here RemActionTiming
|
||||
func TestApierRemActionTiming(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
var rmReply string
|
||||
rmReq := AttrRemActionTiming{ActionTimingsId: "ATMS_1", Tenant: "cgrates.org", Account:"dan4", Direction: "*out"}
|
||||
if err := rater.Call("ApierV1.RemActionTiming", rmReq, &rmReply); err != nil {
|
||||
t.Error("Got error on ApierV1.RemActionTiming: ", err.Error())
|
||||
} else if rmReply != OK {
|
||||
t.Error("Unexpected answer received", rmReply)
|
||||
}
|
||||
var reply []*AccountActionTiming
|
||||
req := AttrAcntAction{Tenant: "cgrates.org", Account:"dan4", Direction: "*out"}
|
||||
if err := rater.Call("ApierV1.GetAccountActionTimings", req, &reply); err != nil {
|
||||
t.Error("Got error on ApierV1.GetAccountActionTimings: ", err.Error())
|
||||
} else if len(reply) != 0 {
|
||||
t.Error("Action timings was not removed")
|
||||
}
|
||||
}
|
||||
|
||||
// Test here GetBalance
|
||||
func TestApierGetBalance(t *testing.T) {
|
||||
if !*testLocal {
|
||||
@@ -1080,6 +1166,52 @@ func TestResponderGetCost(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCdrServer(t *testing.T) {
|
||||
httpClient := new(http.Client)
|
||||
cdrForm1 := url.Values{"accid": []string{"dsafdsaf"}, "cdrhost": []string{"192.168.1.1"}, "reqtype": []string{"rated"}, "direction": []string{"*out"},
|
||||
"tenant": []string{"cgrates.org"}, "tor": []string{"call"}, "account": []string{"1001"}, "subject": []string{"1001"}, "destination": []string{"1002"},
|
||||
"answer_time": []string{"2013-11-07T08:42:26Z"}, "duration": []string{"10"}, "field_extr1": []string{"val_extr1"}, "fieldextr2": []string{"valextr2"}}
|
||||
cdrForm2 := url.Values{"accid": []string{"adsafdsaf"}, "cdrhost": []string{"192.168.1.1"}, "reqtype": []string{"rated"}, "direction": []string{"*out"},
|
||||
"tenant": []string{"cgrates.org"}, "tor": []string{"call"}, "account": []string{"1001"}, "subject": []string{"1001"}, "destination": []string{"1002"},
|
||||
"answer_time": []string{"2013-11-07T08:42:26Z"}, "duration": []string{"10"}, "field_extr1": []string{"val_extr1"}, "fieldextr2": []string{"valextr2"}}
|
||||
for _, cdrForm := range []url.Values{cdrForm1, cdrForm2} {
|
||||
cdrForm.Set(utils.CDRSOURCE, engine.TEST_SQL)
|
||||
if _, err := httpClient.PostForm(fmt.Sprintf("http://%s/cgr", cfg.CdrcCdrs), cdrForm); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExportCdrsToFile(t *testing.T) {
|
||||
var reply *utils.ExportedFileCdrs
|
||||
req := utils.AttrExpFileCdrs{}
|
||||
if err := rater.Call("ApierV1.ExportCdrsToFile", req, &reply); err == nil || !strings.HasPrefix(err.Error(), utils.ERR_MANDATORY_IE_MISSING) {
|
||||
t.Error("Failed to detect missing parameter")
|
||||
}
|
||||
req.CdrFormat = utils.CDRE_DRYRUN
|
||||
expectReply := &utils.ExportedFileCdrs{NumberOfRecords: 2}
|
||||
if err := rater.Call("ApierV1.ExportCdrsToFile", req, &reply); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(reply, expectReply) {
|
||||
t.Errorf("Unexpected reply: %v", reply)
|
||||
}
|
||||
/* Need to implement temporary file writing in order to test removal from db, not possible on DRYRUN
|
||||
req.RemoveFromDb = true
|
||||
if err := rater.Call("ApierV1.ExportCdrsToFile", req, &reply); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(reply, expectReply) {
|
||||
t.Errorf("Unexpected reply: %v", reply)
|
||||
}
|
||||
expectReply.NumberOfRecords = 0 // We should have deleted previously
|
||||
if err := rater.Call("ApierV1.ExportCdrsToFile", req, &reply); err != nil {
|
||||
t.Error(err.Error())
|
||||
} else if !reflect.DeepEqual(reply, expectReply) {
|
||||
t.Errorf("Unexpected reply: %v", reply)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// Simply kill the engine after we are done with tests within this file
|
||||
func TestStopEngine(t *testing.T) {
|
||||
if !*testLocal {
|
||||
|
||||
@@ -65,6 +65,7 @@ var (
|
||||
schedEnabled = flag.Bool("scheduler", false, "Enforce starting of the scheduler daemon overwriting config")
|
||||
cdrsEnabled = flag.Bool("cdrs", false, "Enforce starting of the cdrs daemon overwriting config")
|
||||
cdrcEnabled = flag.Bool("cdrc", false, "Enforce starting of the cdrc service overwriting config")
|
||||
mediatorEnabled = flag.Bool("mediator", false, "Enforce starting of the mediator service overwriting config")
|
||||
pidFile = flag.String("pid", "", "Write pid file")
|
||||
bal = balancer2go.NewBalancer()
|
||||
exitChan = make(chan bool)
|
||||
@@ -373,6 +374,9 @@ func main() {
|
||||
if *cdrcEnabled {
|
||||
cfg.CdrcEnabled = *cdrcEnabled
|
||||
}
|
||||
if *mediatorEnabled {
|
||||
cfg.MediatorEnabled = *mediatorEnabled
|
||||
}
|
||||
if cfg.RaterEnabled {
|
||||
if err := ratingDb.CacheRating(nil, nil, nil); err != nil {
|
||||
engine.Logger.Crit(fmt.Sprintf("Cache rating error: %v", err))
|
||||
|
||||
@@ -758,11 +758,12 @@ func (self *SQLStorage) GetRatedCdrs(timeStart, timeEnd time.Time) ([]*utils.Rat
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var cgrid, accid, cdrhost, cdrsrc, reqtype, direction, tenant, tor, account, subject, destination, runid string
|
||||
var cgrid, accid, cdrhost, cdrsrc, reqtype, direction, tenant, tor, account, subject, destination string
|
||||
var extraFields []byte
|
||||
var answerTime time.Time
|
||||
var duration int64
|
||||
var cost float64
|
||||
var runid sql.NullString // So we can export unmediated CDRs
|
||||
var cost sql.NullFloat64 // So we can export unmediated CDRs
|
||||
var extraFieldsMp map[string]string
|
||||
if err := rows.Scan(&cgrid, &accid, &cdrhost, &cdrsrc, &reqtype, &direction, &tenant, &tor, &account, &subject, &destination, &answerTime, &duration,
|
||||
&extraFields, &runid, &cost); err != nil {
|
||||
@@ -774,7 +775,7 @@ func (self *SQLStorage) GetRatedCdrs(timeStart, timeEnd time.Time) ([]*utils.Rat
|
||||
storCdr := &utils.RatedCDR{
|
||||
CgrId: cgrid, AccId: accid, CdrHost: cdrhost, CdrSource: cdrsrc, ReqType: reqtype, Direction: direction, Tenant: tenant,
|
||||
TOR: tor, Account: account, Subject: subject, Destination: destination, AnswerTime: answerTime, Duration: time.Duration(duration),
|
||||
ExtraFields: extraFieldsMp, MediationRunId: runid, Cost: cost,
|
||||
ExtraFields: extraFieldsMp, MediationRunId: runid.String, Cost: cost.Float64,
|
||||
}
|
||||
cdrs = append(cdrs, storCdr)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user