diff --git a/agents/asterisk_event.go b/agents/asterisk_event.go index f29ecceb1..da0989e82 100644 --- a/agents/asterisk_event.go +++ b/agents/asterisk_event.go @@ -175,85 +175,12 @@ func (smaEv *SMAsteriskEvent) ExtraParameters() (extraParams map[string]string) return } -func (smaEv *SMAsteriskEvent) AsSMGenericEvent() *sessions.SMGenericEvent { - var evName string - switch smaEv.EventType() { - case ARIStasisStart: - evName = SMAAuthorization - case ARIChannelStateChange: - evName = SMASessionStart - case ARIChannelDestroyed: - evName = SMASessionTerminate - } - smgEv := sessions.SMGenericEvent{utils.EVENT_NAME: evName} - smgEv[utils.OriginID] = smaEv.ChannelID() - if smaEv.RequestType() != "" { - smgEv[utils.RequestType] = smaEv.RequestType() - } - if smaEv.Tenant() != "" { - smgEv[utils.Tenant] = smaEv.Tenant() - } - if smaEv.Category() != "" { - smgEv[utils.Category] = smaEv.Category() - } - if smaEv.Subject() != "" { - smgEv[utils.Subject] = smaEv.Subject() - } - smgEv[utils.OriginHost] = smaEv.OriginatorIP() - smgEv[utils.Account] = smaEv.Account() - smgEv[utils.Destination] = smaEv.Destination() - smgEv[utils.SetupTime] = smaEv.Timestamp() - if smaEv.Supplier() != "" { - smgEv[utils.SUPPLIER] = smaEv.Supplier() - } - for extraKey, extraVal := range smaEv.ExtraParameters() { // Append extraParameters - smgEv[extraKey] = extraVal - } - return &smgEv -} - -// Updates fields in smgEv based on own fields -// Using pointer so we update it directly in cache -func (smaEv *SMAsteriskEvent) UpdateSMGEvent(smgEv *sessions.SMGenericEvent) error { - resSMGEv := *smgEv - switch smaEv.EventType() { - case ARIChannelStateChange: - if smaEv.ChannelState() == channelUp { - resSMGEv[utils.EVENT_NAME] = SMASessionStart - resSMGEv[utils.AnswerTime] = smaEv.Timestamp() - } - case ARIChannelDestroyed: - resSMGEv[utils.EVENT_NAME] = SMASessionTerminate - resSMGEv[utils.DISCONNECT_CAUSE] = smaEv.DisconnectCause() - if _, hasIt := resSMGEv[utils.AnswerTime]; !hasIt { - resSMGEv[utils.Usage] = "0s" - } else { - - if aTime, err := smgEv.GetAnswerTime(utils.META_DEFAULT, ""); err != nil { - return err - } else if aTime.IsZero() { - resSMGEv[utils.Usage] = "0s" - } else { - actualTime, err := utils.ParseTimeDetectLayout(smaEv.Timestamp(), "") - if err != nil { - return err - } - resSMGEv[utils.Usage] = actualTime.Sub(aTime).String() - } - } - } - *smgEv = resSMGEv - return nil -} - func (smaEv *SMAsteriskEvent) UpdateCGREvent(cgrEv *utils.CGREvent) error { resCGREv := *cgrEv switch smaEv.EventType() { case ARIChannelStateChange: - if smaEv.ChannelState() == channelUp { - resCGREv.Event[utils.EVENT_NAME] = SMASessionStart - resCGREv.Event[utils.AnswerTime] = smaEv.Timestamp() - } + resCGREv.Event[utils.EVENT_NAME] = SMASessionStart + resCGREv.Event[utils.AnswerTime] = smaEv.Timestamp() case ARIChannelDestroyed: resCGREv.Event[utils.EVENT_NAME] = SMASessionTerminate resCGREv.Event[utils.DISCONNECT_CAUSE] = smaEv.DisconnectCause() @@ -305,7 +232,7 @@ func (smaEv *SMAsteriskEvent) AsMapStringInterface() (mp map[string]interface{}) mp[utils.OriginHost] = smaEv.OriginatorIP() mp[utils.Account] = smaEv.Account() mp[utils.Destination] = smaEv.Destination() - mp[utils.SetupTime] = smaEv.Timestamp() + mp[utils.SetupTime] = smaEv.SetupTime() if smaEv.Supplier() != "" { mp[utils.SUPPLIER] = smaEv.Supplier() } @@ -375,14 +302,10 @@ func (smaEv *SMAsteriskEvent) V1AuthorizeArgs() (args *sessions.V1AuthorizeArgs) return } -func (smaEv *SMAsteriskEvent) V1InitSessionArgs() (args *sessions.V1InitSessionArgs) { - cgrEv, err := smaEv.AsCGREvent(config.CgrConfig().DefaultTimezone) - if err != nil { - return - } +func (smaEv *SMAsteriskEvent) V1InitSessionArgs(cgrEv utils.CGREvent) (args *sessions.V1InitSessionArgs) { args = &sessions.V1InitSessionArgs{ // defaults InitSession: true, - CGREvent: *cgrEv, + CGREvent: cgrEv, } /* subsystems, has := kev[KamCGRSubsystems] @@ -408,14 +331,10 @@ func (smaEv *SMAsteriskEvent) V1InitSessionArgs() (args *sessions.V1InitSessionA return } -func (smaEv *SMAsteriskEvent) V1TerminateSessionArgs() (args *sessions.V1TerminateSessionArgs) { - cgrEv, err := smaEv.AsCGREvent(config.CgrConfig().DefaultTimezone) - if err != nil { - return - } +func (smaEv *SMAsteriskEvent) V1TerminateSessionArgs(cgrEv utils.CGREvent) (args *sessions.V1TerminateSessionArgs) { args = &sessions.V1TerminateSessionArgs{ // defaults TerminateSession: true, - CGREvent: *cgrEv, + CGREvent: cgrEv, } /* subsystems, has := kev[KamCGRSubsystems] diff --git a/agents/asterisk_event_test.go b/agents/asterisk_event_test.go index ef12a07e3..ba31b3ae6 100644 --- a/agents/asterisk_event_test.go +++ b/agents/asterisk_event_test.go @@ -21,9 +21,6 @@ import ( "encoding/json" "reflect" "testing" - - "github.com/cgrates/cgrates/sessions" - "github.com/cgrates/cgrates/utils" ) var ( @@ -328,212 +325,3 @@ func TestSMAEventExtraParameters(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v", expExtraParams, extraParams) } } - -/* -func TestSMAEventUpdateFromEvent(t *testing.T) { - var ev map[string]interface{} - if err := json.Unmarshal([]byte(stasisStart), &ev); err != nil { - t.Error(err) - } - smaEv := NewSMAsteriskEvent(ev, "127.0.0.1") - ev = make(map[string]interface{}) - if err := json.Unmarshal([]byte(channelAnsweredDestroyed), &ev); err != nil { - t.Error(err) - } - smaEv2 := NewSMAsteriskEvent(ev, "127.0.0.1") - smaEv.UpdateFromEvent(smaEv2) - eSMAEv := &SMAsteriskEvent{ - ariEv: map[string]interface{}{ - "type": "ChannelDestroyed", - "args": []interface{}{"cgr_reqtype=*prepaid", "cgr_destination=1003", "extra1=val1", "extra2=val2"}, - "timestamp": "2016-09-12T13:54:27.335+0200", - "application": "cgrates_auth", - "cause_txt": "Normal Clearing", - "channel": map[string]interface{}{ - "id": "1473681228.6", - "state": "Up", - "name": "PJSIP/1001-00000004", - "caller": map[string]interface{}{ - "name": "1001", - "number": "1001"}, - "language": "en", - "connected": map[string]interface{}{ - "name": "", - "number": "1002"}, - "accountcode": "", - "dialplan": map[string]interface{}{ - "context": "internal", - "exten": "1002", - "priority": 3.0}, - "creationtime": "2016-09-12T13:53:48.918+0200"}, - "cause": 16.0}, - asteriskIP: "127.0.0.1", - cachedFields: map[string]string{"cgr_reqtype": "*prepaid", - "cgr_destination": "1003", "extra1": "val1", "extra2": "val2"}, - } - if !reflect.DeepEqual(eSMAEv, smaEv) { - t.Errorf("Expecting: %+v, received: %+v", eSMAEv, smaEv) - } -} -*/ - -//Here -func TestSMAEventAsSMGenericEvent(t *testing.T) { - var ev map[string]interface{} - if err := json.Unmarshal([]byte(stasisStart), &ev); err != nil { - t.Error(err) - } - eSMGEv := &sessions.SMGenericEvent{ - utils.EVENT_NAME: SMAAuthorization, - utils.OriginID: "1473681228.6", - utils.RequestType: "*prepaid", - utils.OriginHost: "127.0.0.1", - utils.Account: "1001", - utils.Destination: "1002", - utils.SetupTime: "2016-09-12T13:53:48.919+0200", - utils.SUPPLIER: "supplier1", - "extra1": "val1", - "extra2": "val2", - } - smaEv := NewSMAsteriskEvent(ev, "127.0.0.1") - if smgEv := smaEv.AsSMGenericEvent(); !reflect.DeepEqual(eSMGEv, smgEv) { - t.Errorf("Expecting: %+v, received: %+v", eSMGEv, smgEv) - } -} - -func TestSMAEventUpdateSMGEventAnswered(t *testing.T) { - var ev map[string]interface{} - if err := json.Unmarshal([]byte(channelStateChange), &ev); err != nil { - t.Error(err) - } - smaEv := NewSMAsteriskEvent(ev, "127.0.0.1") - smgEv := &sessions.SMGenericEvent{ - utils.EVENT_NAME: SMAAuthorization, - utils.OriginID: "1473681228.6", - utils.RequestType: "*prepaid", - utils.OriginHost: "127.0.0.1", - utils.Account: "1001", - utils.Destination: "1003", - utils.SetupTime: "2016-09-12T13:53:48.919+0200", - "extra1": "val1", - "extra2": "val2", - } - eSMGEv := &sessions.SMGenericEvent{ - utils.EVENT_NAME: SMASessionStart, - utils.OriginID: "1473681228.6", - utils.RequestType: "*prepaid", - utils.OriginHost: "127.0.0.1", - utils.Account: "1001", - utils.Destination: "1003", - utils.SetupTime: "2016-09-12T13:53:48.919+0200", - utils.AnswerTime: "2016-09-12T13:53:52.110+0200", - "extra1": "val1", - "extra2": "val2", - } - if err := smaEv.UpdateSMGEvent(smgEv); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(eSMGEv, smgEv) { - t.Errorf("Expecting: %+v, received: %+v", eSMGEv, smgEv) - } - // Apply update using a terminate event - ev = make(map[string]interface{}) - if err = json.Unmarshal([]byte(channelAnsweredDestroyed), &ev); err != nil { - t.Error(err) - } - smaEv = NewSMAsteriskEvent(ev, "127.0.0.1") - eSMGEv = &sessions.SMGenericEvent{ - utils.EVENT_NAME: SMASessionTerminate, - utils.OriginID: "1473681228.6", - utils.RequestType: "*prepaid", - utils.OriginHost: "127.0.0.1", - utils.Account: "1001", - utils.Destination: "1003", - utils.SetupTime: "2016-09-12T13:53:48.919+0200", - utils.AnswerTime: "2016-09-12T13:53:52.110+0200", - utils.Usage: "35.225s", - utils.DISCONNECT_CAUSE: "Normal Clearing", - "extra1": "val1", - "extra2": "val2", - } - if err := smaEv.UpdateSMGEvent(smgEv); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(eSMGEv, smgEv) { - t.Errorf("Expecting: %+v, received: %+v", eSMGEv, smgEv) - } -} - -func TestSMAEventUpdateSMGEventUnaswered(t *testing.T) { - smgEv := &sessions.SMGenericEvent{ - utils.EVENT_NAME: SMAAuthorization, - utils.OriginID: "1473681228.6", - utils.RequestType: "*prepaid", - utils.OriginHost: "127.0.0.1", - utils.Account: "1001", - utils.Destination: "1003", - utils.SetupTime: "2016-09-12T13:53:48.919+0200", - "extra1": "val1", - "extra2": "val2", - } - eSMGEv := &sessions.SMGenericEvent{ - utils.EVENT_NAME: SMASessionTerminate, - utils.OriginID: "1473681228.6", - utils.RequestType: "*prepaid", - utils.OriginHost: "127.0.0.1", - utils.Account: "1001", - utils.Destination: "1003", - utils.SetupTime: "2016-09-12T13:53:48.919+0200", - utils.Usage: "0s", - utils.DISCONNECT_CAUSE: "Normal Clearing", - "extra1": "val1", - "extra2": "val2", - } - // Apply update using a terminate event - ev := make(map[string]interface{}) - if err := json.Unmarshal([]byte(channelUnansweredDestroyed), &ev); err != nil { - t.Error(err) - } - smaEv := NewSMAsteriskEvent(ev, "127.0.0.1") - if err := smaEv.UpdateSMGEvent(smgEv); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(eSMGEv, smgEv) { - t.Errorf("Expecting: %+v, received: %+v", eSMGEv, smgEv) - } -} - -func TestSMAEventUpdateSMGEventBusy(t *testing.T) { - smgEv := &sessions.SMGenericEvent{ - utils.EVENT_NAME: SMAAuthorization, - utils.OriginID: "1473681228.6", - utils.RequestType: "*prepaid", - utils.OriginHost: "127.0.0.1", - utils.Account: "1001", - utils.Destination: "1003", - utils.SetupTime: "2016-09-12T13:53:48.919+0200", - "extra1": "val1", - "extra2": "val2", - } - eSMGEv := &sessions.SMGenericEvent{ - utils.EVENT_NAME: SMASessionTerminate, - utils.OriginID: "1473681228.6", - utils.RequestType: "*prepaid", - utils.OriginHost: "127.0.0.1", - utils.Account: "1001", - utils.Destination: "1003", - utils.SetupTime: "2016-09-12T13:53:48.919+0200", - utils.Usage: "0s", - utils.DISCONNECT_CAUSE: "User busy", - "extra1": "val1", - "extra2": "val2", - } - // Apply update using a terminate event - ev := make(map[string]interface{}) - if err := json.Unmarshal([]byte(channelBusyDestroyed), &ev); err != nil { - t.Error(err) - } - smaEv := NewSMAsteriskEvent(ev, "127.0.0.1") - if err := smaEv.UpdateSMGEvent(smgEv); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(eSMGEv, smgEv) { - t.Errorf("Expecting: %+v, received: %+v", eSMGEv, smgEv) - } -} diff --git a/agents/asteriskagent.go b/agents/asteriskagent.go index 44bc50312..ccb355258 100644 --- a/agents/asteriskagent.go +++ b/agents/asteriskagent.go @@ -136,8 +136,6 @@ func (sma *AsteriskAgent) handleStasisStart(ev *SMAsteriskEvent) { utils.AsteriskAgent, ev.ChannelID())) return } - // var maxUsage float64 - // smgEv := ev.AsSMGenericEvent() var authReply sessions.V1AuthorizeReply if err := sma.smg.Call(utils.SessionSv1AuthorizeEvent, authArgs, &authReply); err != nil { utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to authorize session for channelID: %s", @@ -161,7 +159,7 @@ func (sma *AsteriskAgent) handleStasisStart(ev *SMAsteriskEvent) { sma.cgrCfg.AsteriskAgentCfg().AsteriskConns[sma.astConnIdx].Address, ev.ChannelID(), CGRMaxSessionTime), url.Values{"value": {strconv.FormatFloat( - float64(authReply.MaxUsage.Nanoseconds())*1000, 'f', -1, 64)}}); err != nil { // Asterisk expects value in ms + float64(authReply.MaxUsage.Miliseconds(), 'f', -1, 64)}}); err != nil { // Asterisk expects value in ms utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when setting %s for channelID: %s", utils.AsteriskAgent, err.Error(), CGRMaxSessionTime, ev.ChannelID())) // Since we got error, disconnect channel @@ -190,18 +188,33 @@ func (sma *AsteriskAgent) handleChannelStateChange(ev *SMAsteriskEvent) { return } sma.evCacheMux.RLock() - _, hasIt := sma.eventsCache[ev.ChannelID()] + cgrEv, hasIt := sma.eventsCache[ev.ChannelID()] sma.evCacheMux.RUnlock() if !hasIt { // Not handled by us return } - - initSessionArgs := ev.V1InitSessionArgs() + sma.evCacheMux.Lock() + err := ev.UpdateCGREvent(cgrEv) // Updates the event directly in the cache + sma.evCacheMux.Unlock() + if err != nil { + utils.Logger.Err( + fmt.Sprintf("<%s> Error: %s when attempting to initiate session for channelID: %s", + utils.AsteriskAgent, err.Error(), ev.ChannelID())) + if err := sma.hangupChannel(ev.ChannelID()); err != nil { + utils.Logger.Err( + fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", + utils.AsteriskAgent, err.Error(), ev.ChannelID())) + } + return + } + // populate init session args + initSessionArgs := ev.V1InitSessionArgs(*cgrEv) if initSessionArgs == nil { utils.Logger.Err(fmt.Sprintf("<%s> event: %s cannot generate init session arguments", utils.AsteriskAgent, ev.ChannelID())) return } + //initit Session var initReply sessions.V1InitSessionReply if err := sma.smg.Call(utils.SessionSv1InitiateSession, @@ -223,63 +236,19 @@ func (sma *AsteriskAgent) handleChannelStateChange(ev *SMAsteriskEvent) { } return } - sma.evCacheMux.Lock() - err := ev.UpdateCGREvent(&initSessionArgs.CGREvent) // Updates the event directly in the cache - sma.evCacheMux.Unlock() - if err != nil { - utils.Logger.Err( - fmt.Sprintf("<%s> Error: %s when attempting to initiate session for channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - if err := sma.hangupChannel(ev.ChannelID()); err != nil { - utils.Logger.Err( - fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } - return - } + } // Channel disconnect func (sma *AsteriskAgent) handleChannelDestroyed(ev *SMAsteriskEvent) { sma.evCacheMux.RLock() - _, hasIt := sma.eventsCache[ev.ChannelID()] + cgrEv, hasIt := sma.eventsCache[ev.ChannelID()] sma.evCacheMux.RUnlock() if !hasIt { // Not handled by us return } - - //terminate session - tsArgs := ev.V1TerminateSessionArgs() - if tsArgs == nil { - utils.Logger.Err(fmt.Sprintf("<%s> event: %s cannot generate terminate session arguments", - utils.AsteriskAgent, ev.ChannelID())) - return - } - var reply string - if err := sma.smg.Call(utils.SessionSv1TerminateSession, - tsArgs, &reply); err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to terminate session for channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } - if sma.cgrCfg.AsteriskAgentCfg().CreateCDR { - setupTime, err := utils.ParseTimeDetectLayout( - ev.SetupTime(), config.CgrConfig().DefaultTimezone) - if err != nil { - return - } - cgrEv := utils.CGREvent{ - Tenant: ev.Tenant(), - ID: utils.UUIDSha1Prefix(), - Time: &setupTime, - Event: ev.AsMapStringInterface(), - } - if err := sma.smg.Call(utils.SessionSv1ProcessCDR, cgrEv, &reply); err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to process CDR for channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } - } sma.evCacheMux.Lock() - err := ev.UpdateCGREvent(&tsArgs.CGREvent) // Updates the event directly in the cache + err := ev.UpdateCGREvent(cgrEv) // Updates the event directly in the cache sma.evCacheMux.Unlock() if err != nil { utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to initiate session for channelID: %s", @@ -290,6 +259,27 @@ func (sma *AsteriskAgent) handleChannelDestroyed(ev *SMAsteriskEvent) { } return } + // populate terminate session args + tsArgs := ev.V1TerminateSessionArgs(*cgrEv) + if tsArgs == nil { + utils.Logger.Err(fmt.Sprintf("<%s> event: %s cannot generate terminate session arguments", + utils.AsteriskAgent, ev.ChannelID())) + return + } + + var reply string + if err := sma.smg.Call(utils.SessionSv1TerminateSession, + tsArgs, &reply); err != nil { + utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to terminate session for channelID: %s", + utils.AsteriskAgent, err.Error(), ev.ChannelID())) + } + if sma.cgrCfg.AsteriskAgentCfg().CreateCDR { + if err := sma.smg.Call(utils.SessionSv1ProcessCDR, *cgrEv, &reply); err != nil { + utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to process CDR for channelID: %s", + utils.AsteriskAgent, err.Error(), ev.ChannelID())) + } + } + } // Called to shutdown the service diff --git a/data/tutorials/asterisk_ari/asterisk/etc/asterisk/pjsip.conf b/data/tutorials/asterisk_ari/asterisk/etc/asterisk/pjsip.conf index b2649d605..e99652665 100755 --- a/data/tutorials/asterisk_ari/asterisk/etc/asterisk/pjsip.conf +++ b/data/tutorials/asterisk_ari/asterisk/etc/asterisk/pjsip.conf @@ -1,7 +1,7 @@ [simpletrans] type=transport protocol=udp -bind=192.168.56.203 +bind=0.0.0.0 [1001] type = endpoint diff --git a/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json b/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json index f28abc914..1d16f47cd 100644 --- a/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json @@ -4,28 +4,24 @@ // Copyright (C) ITsysCOM GmbH "general": { - "http_skip_tls_verify": false, // if enabled Http Client will accept any TLS certificate - "rounding_decimals": 5, // system level precision for floats - "dbdata_encoding": "msgpack", // encoding used to store object data in strings: - "tpexport_dir": "/var/spool/cgrates/tpe", // path towards export folder for offline Tariff Plans - "httpposter_attempts": 3, // number of http attempts before considering request failed (eg: *call_url) - "default_request_type": "*rated", // default request type to consider when missing from requests: <""|*prepaid|*postpaid|*pseudoprepaid|*rated> - "default_category": "call", // default category to consider when missing from requests - "default_tenant": "cgrates.org", // default tenant to consider when missing from requests - "default_timezone": "Local", // default timezone for timestamps where not specified <""|UTC|Local|$IANA_TZ_DB> - "connect_attempts": 3, // initial server connect attempts - "reconnects": -1, // number of retries in case of connection lost - "connect_timeout": "1s", // consider connection unsuccessful on timeout, 0 to disable the feature - "reply_timeout": "2s", // consider connection down for replies taking longer than this value - "response_cache_ttl": "0s", // the life span of a cached response - "internal_ttl": "2m", // maximum duration to wait for internal connections before giving up - "locking_timeout": "5s", // timeout internal locks to avoid deadlocks - "cache_dump_dir": "", // cache dump for faster start (leave empty to disable) + "log_level": 7, }, -"stor_db": { // database used to store offline tariff plans and CDRs - "db_password": "CGRateS.org", // password to use when connecting to stordb +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", +}, + + +"stor_db": { + "db_password": "CGRateS.org", +}, + + +"scheduler": { + "enabled": true, }, @@ -84,9 +80,6 @@ "debit_interval": "10s", }, -"scheduler": { - "enabled": true, -}, "cdre": { "*default": { diff --git a/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json b/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json index 1ced3cd15..1fae4a39c 100644 --- a/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json @@ -1,15 +1,13 @@ { -// Real-time Charging System for Telecom & ISP environments +// Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments // Copyright (C) ITsysCOM GmbH -// -// This file contains the default configuration hardcoded into CGRateS. -// This is what you get when you load CGRateS with an empty configuration file. "general": { "log_level": 7, }, + "listen": { "rpc_json": ":2012", "rpc_gob": ":2013", diff --git a/general_tests/tutorial_astevents_calls_test.go b/general_tests/tutorial_astevents_calls_test.go deleted file mode 100644 index 218cb6f74..000000000 --- a/general_tests/tutorial_astevents_calls_test.go +++ /dev/null @@ -1,484 +0,0 @@ -// +build calls - -/* -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 -*/ - -package general_tests - -import ( - "net/rpc" - "net/rpc/jsonrpc" - "os" - "path" - "reflect" - "testing" - "time" - - "github.com/cgrates/cgrates/apier/v1" - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -const astPassword = "CGRateS.org" - -var tutAstCallsCfg *config.CGRConfig -var tutAstCallsRpc *rpc.Client -var tutAstCallsPjSuaListener *os.File - -func TestTutAstCallsInitCfg(t *testing.T) { - // Init config first - var err error - tutAstCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*dataDir, "tutorials", "asterisk_ari", "cgrates", "etc", "cgrates")) - if err != nil { - t.Error(err) - } - tutAstCallsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() - config.SetCgrConfig(tutAstCallsCfg) -} - -// Remove data in both rating and accounting db -func TestTutAstCallsResetDataDb(t *testing.T) { - if err := engine.InitDataDb(tutAstCallsCfg); err != nil { - t.Fatal(err) - } -} - -// Wipe out the cdr database -func TestTutAstCallsResetStorDb(t *testing.T) { - if err := engine.InitStorDb(tutAstCallsCfg); err != nil { - t.Fatal(err) - } -} - -// start Asterisk server -func TestTutAstCallsStartAsterisk(t *testing.T) { - engine.KillProcName("asterisk", 1000) - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "asterisk_ari", "asterisk", "etc", "init.d", "asterisk"), "start", 2000); err != nil { - t.Fatal(err) - } -} - -// Start CGR Engine -func TestTutAstCallsStartEngine(t *testing.T) { - engine.KillProcName("cgr-engine", *waitRater) - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "asterisk_ari", "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { - t.Fatal(err) - } -} - -/* -// Restart FS so we make sure reconnects are working -func TestTutAstCallsRestartAsterisk(t *testing.T) { - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "asterisk_ari", "asterisk", "etc", "init.d", "asterisk"), "restart", 2000); err != nil { - t.Fatal(err) - } -} -*/ -// Connect rpc client to rater -func TestTutAstCallsRpcConn(t *testing.T) { - var err error - tutAstCallsRpc, err = jsonrpc.Dial("tcp", tutAstCallsCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -// Load the tariff plan, creating accounts and their balances -func TestTutAstCallsLoadTariffPlanFromFolder(t *testing.T) { - reply := "" - attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} - if err := tutAstCallsRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Error(reply) - } - time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups -} - -// Make sure account was debited properly -func TestTutAstCallsAccountsBefore(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutAstCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1002"} - if err := tutAstCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1003"} - if err := tutAstCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1004"} - if err := tutAstCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1007"} - if err := tutAstCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 0.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1005"} - if err := tutAstCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error("Got error on ApierV2.GetAccount: %v", err) - } -} - -// Make sure all stats queues are in place -func TestTutAstCallsCdrStatsBefore(t *testing.T) { - //eQueueIds := []string{"*default", "CDRST1", "CDRST_1001", "CDRST_1002", "CDRST_1003", "STATS_SUPPL1", "STATS_SUPPL2"} - var statMetrics map[string]float64 - eMetrics := map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutAstCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST1"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACC: -1, engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1} - if err := tutAstCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1001"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutAstCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1002"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutAstCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1003"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutAstCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL1"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutAstCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL2"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } -} - -// Start Pjsua as listener and register it to receive calls -func TestTutAstCallsStartPjsuaListener(t *testing.T) { - var err error - acnts := []*engine.PjsuaAccount{ - &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: astPassword, Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: astPassword, Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: astPassword, Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1004@127.0.0.1", Username: "1004", Password: astPassword, Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1006@127.0.0.1", Username: "1006", Password: astPassword, Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1007@127.0.0.1", Username: "1007", Password: astPassword, Realm: "*", Registrar: "sip:127.0.0.1:5060"}} - if tutAstCallsPjSuaListener, err = engine.StartPjsuaListener(acnts, 5070, time.Duration(500*time.Millisecond)); err != nil { - t.Fatal(err) - } -} - -// Call from 1001 (prepaid) to 1002 -func TestTutAstCallsCall1001To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: astPassword, Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(67)*time.Second, 5071); err != nil { - t.Fatal(err) - } -} - -// Call from 1001 (prepaid) to 1003 -func TestTutAstCallsCall1001To1003(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: astPassword, Realm: "*"}, "sip:1003@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(65)*time.Second, 5072); err != nil { - t.Fatal(err) - } -} - -func TestTutAstCallsCall1002To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: astPassword, Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(61)*time.Second, 5073); err != nil { - t.Fatal(err) - } -} - -func TestTutAstCallsCall1003To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: astPassword, Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(63)*time.Second, 5074); err != nil { - t.Fatal(err) - } -} - -func TestTutAstCallsCall1004To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1004@127.0.0.1", Username: "1004", Password: astPassword, Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(62)*time.Second, 5075); err != nil { - t.Fatal(err) - } -} - -func TestTutAstCallsCall1006To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1006@127.0.0.1", Username: "1006", Password: astPassword, Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(64)*time.Second, 5076); err != nil { - t.Fatal(err) - } -} - -func TestTutAstCallsCall1007To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1007@127.0.0.1", Username: "1007", Password: astPassword, Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(66)*time.Second, 5077); err != nil { - t.Fatal(err) - } -} - -// Make sure account was debited properly -func TestTutAstCallsAccount1001(t *testing.T) { - time.Sleep(time.Duration(70) * time.Second) // Allow calls to finish before start querying the results - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutAstCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() == 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } else if reply.Disabled == true { - t.Error("Account disabled") - } -} - -// Make sure account was debited properly -func TestTutAstCalls1001Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - //var cgrId string // Share with getCostDetails - //var cCost engine.CallCost - req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}, DestinationPrefixes: []string{"1002"}} - if err := tutAstCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - //cgrId = reply[0].CGRID - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Usage != "67" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost == -1.0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - //if reply[0].Supplier != "suppl2" { // Usage as seconds - // t.Errorf("Unexpected Supplier for CDR: %+v", reply[0]) - //} - } - req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}, DestinationPrefixes: []string{"1003"}} - if err := tutAstCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - //cgrId = reply[0].CGRID - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Usage != "65" && reply[0].Usage != "66" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost != 0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - } - req = utils.RPCCDRsFilter{Accounts: []string{"1001"}, RunIDs: []string{"derived_run1"}} - if err := tutAstCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].RequestType != utils.META_RATED { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Subject != "1002" { - t.Errorf("Unexpected Subject for CDR: %+v", reply[0]) - } - } - -} - -// Make sure account was debited properly -func TestTutAstCalls1002Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1002"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutAstCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_POSTPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "61" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } -} - -// Make sure account was debited properly -func TestTutAstCalls1003Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1003"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutAstCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PSEUDOPREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "63" && reply[0].Usage != "64" { // Usage as seconds, sometimes takes a second longer to disconnect - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } - -} - -// Make sure account was debited properly -func TestTutAstCalls1004Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1004"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutAstCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_RATED { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "62" && reply[0].Usage != "63" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } - -} - -// Make sure aliasing was done for 1006 and we have no CDRs for it -func TestTutAstCalls1006Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1006"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutAstCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 0 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } -} - -// Make sure account was debited properly -func TestTutAstCalls1007Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1007"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutAstCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1002" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "66" && reply[0].Usage != "67" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost == -1.0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - } -} - -// Make sure account was debited properly -func TestTutAstCallsAccountFraud1001(t *testing.T) { - var reply string - attrAddBlnc := &v1.AttrAddBalance{Tenant: "cgrates.org", Account: "1001", BalanceType: "*monetary", Value: 101} - if err := tutAstCallsRpc.Call("ApierV1.AddBalance", attrAddBlnc, &reply); err != nil { - t.Error("Got error on ApierV1.AddBalance: ", err.Error()) - } else if reply != "OK" { - t.Errorf("Calling ApierV1.AddBalance received: %s", reply) - } -} - -// Based on Fraud automatic mitigation, our account should be disabled -func TestTutAstCallsAccountDisabled1001(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutAstCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.Disabled == false { - t.Error("Account should be disabled per fraud detection rules.") - } -} - -func TestTutAstCallsStopPjsuaListener(t *testing.T) { - time.Sleep(70 * time.Second) // Give time for calls to go through before unregistering - tutAstCallsPjSuaListener.Write([]byte("q\n")) // Close pjsua - time.Sleep(time.Duration(1) * time.Second) // Allow pjsua to finish it's tasks, eg un-REGISTER -} - -func TestTutAstCallsStopCgrEngine(t *testing.T) { - if err := engine.KillEngine(100); err != nil { - t.Error(err) - } -} - -func TestTutAstCallsStopAsterisk(t *testing.T) { - engine.KillProcName("asterisk", 100) -} diff --git a/general_tests/tut_fs_calls_test.go b/general_tests/tutorial_calls_test.go similarity index 79% rename from general_tests/tut_fs_calls_test.go rename to general_tests/tutorial_calls_test.go index ff65357b8..077dc549f 100755 --- a/general_tests/tut_fs_calls_test.go +++ b/general_tests/tutorial_calls_test.go @@ -1,4 +1,4 @@ -// +build newcall +// +build call /* Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments @@ -22,7 +22,6 @@ package general_tests import ( "flag" - "fmt" "net/rpc" "net/rpc/jsonrpc" "os" @@ -37,14 +36,15 @@ import ( "github.com/cgrates/cgrates/utils" ) -var tutFsCallsCfg *config.CGRConfig -var tutFsCallsRpc *rpc.Client -var tutFsCallsPjSuaListener *os.File +var tutorialCallsCfg *config.CGRConfig +var tutorialCallsRpc *rpc.Client +var tutorialCallsPjSuaListener *os.File var waitRater = flag.Int("wait_rater", 100, "Number of miliseconds to wait for rater to start and cache") var dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") var fsConfig = flag.String("fsConfig", "/usr/share/cgrates/tutorials/fs_evsock", "FreeSwitch tutorial folder") var kamConfig = flag.String("kamConfig", "/usr/share/cgrates/tutorials/kamevapi", "Kamailio tutorial folder") var oSipsConfig = flag.String("osConfig", "/usr/share/cgrates/tutorials/osips_native", "OpenSips tutorial folder") +var ariConf = flag.String("ariConf", "/usr/share/cgrates/tutorials/asterisk_ari", "Asterisk tutorial folder") var optConf string var sTestsCalls = []func(t *testing.T){ @@ -80,61 +80,73 @@ var sTestsCalls = []func(t *testing.T){ } //Test start here -func TestFSCalls(t *testing.T) { +func TestFreeswitchCalls(t *testing.T) { optConf = utils.Freeswitch for _, stest := range sTestsCalls { t.Run("", stest) } } -func TestKamCalls(t *testing.T) { +func TestKamailioCalls(t *testing.T) { optConf = utils.Kamailio for _, stest := range sTestsCalls { t.Run("", stest) } } -func TestOSCalls(t *testing.T) { +func TestOpensipsCalls(t *testing.T) { optConf = utils.Opensips for _, stest := range sTestsCalls { t.Run("", stest) } } +func TestAsteriskCalls(t *testing.T) { + optConf = utils.Asterisk + for _, stest := range sTestsCalls { + t.Run("", stest) + } +} + func testCallInitCfg(t *testing.T) { // Init config first var err error if optConf == utils.Freeswitch { - tutFsCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*fsConfig, "cgrates", "etc", "cgrates")) + tutorialCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*fsConfig, "cgrates", "etc", "cgrates")) if err != nil { t.Error(err) } } else if optConf == utils.Kamailio { - tutFsCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*kamConfig, "cgrates", "etc", "cgrates")) + tutorialCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*kamConfig, "cgrates", "etc", "cgrates")) if err != nil { t.Error(err) } } else if optConf == utils.Opensips { - tutFsCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*oSipsConfig, "cgrates", "etc", "cgrates")) + tutorialCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*oSipsConfig, "cgrates", "etc", "cgrates")) + if err != nil { + t.Error(err) + } + } else if optConf == utils.Asterisk { + tutorialCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*ariConf, "cgrates", "etc", "cgrates")) if err != nil { t.Error(err) } } - tutFsCallsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() - config.SetCgrConfig(tutFsCallsCfg) + tutorialCallsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() + config.SetCgrConfig(tutorialCallsCfg) } // Remove data in both rating and accounting db func testCallResetDataDb(t *testing.T) { - if err := engine.InitDataDb(tutFsCallsCfg); err != nil { + if err := engine.InitDataDb(tutorialCallsCfg); err != nil { t.Fatal(err) } } // Wipe out the cdr database func testCallResetStorDb(t *testing.T) { - if err := engine.InitStorDb(tutFsCallsCfg); err != nil { + if err := engine.InitStorDb(tutorialCallsCfg); err != nil { t.Fatal(err) } } @@ -156,6 +168,11 @@ func testCallStartFS(t *testing.T) { if err := engine.CallScript(path.Join(*oSipsConfig, "opensips", "etc", "init.d", "opensips"), "start", 3000); err != nil { t.Fatal(err) } + } else if optConf == utils.Asterisk { + engine.KillProcName(utils.Asterisk, 5000) + if err := engine.CallScript(path.Join(*ariConf, "asterisk", "etc", "init.d", "asterisk"), "start", 3000); err != nil { + t.Fatal(err) + } } } @@ -174,6 +191,10 @@ func testCallStartEngine(t *testing.T) { if err := engine.CallScript(path.Join(*oSipsConfig, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { t.Fatal(err) } + } else if optConf == utils.Asterisk { + if err := engine.CallScript(path.Join(*ariConf, "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { + t.Fatal(err) + } } } @@ -191,13 +212,17 @@ func testCallRestartFS(t *testing.T) { if err := engine.CallScript(path.Join(*oSipsConfig, "opensips", "etc", "init.d", "opensips"), "restart", 5000); err != nil { t.Fatal(err) } + } else if optConf == utils.Asterisk { + if err := engine.CallScript(path.Join(*ariConf, "asterisk", "etc", "init.d", "asterisk"), "restart", 5000); err != nil { + t.Fatal(err) + } } } // Connect rpc client to rater func testCallRpcConn(t *testing.T) { var err error - tutFsCallsRpc, err = jsonrpc.Dial("tcp", tutFsCallsCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed + tutorialCallsRpc, err = jsonrpc.Dial("tcp", tutorialCallsCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed if err != nil { t.Fatal(err) } @@ -208,7 +233,7 @@ func testCallRpcConn(t *testing.T) { func testCallLoadTariffPlanFromFolder(t *testing.T) { var reply string attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial2")} - if err := tutFsCallsRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { + if err := tutorialCallsRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { t.Error(err) } time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups @@ -218,14 +243,14 @@ func testCallLoadTariffPlanFromFolder(t *testing.T) { func testCallAccountsBefore(t *testing.T) { var reply *engine.Account attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { + if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { t.Error("Got error on ApierV2.GetAccount: ", err.Error()) } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) } var reply2 *engine.Account attrs2 := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1002"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs2, &reply2); err != nil { + if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs2, &reply2); err != nil { t.Error("Got error on ApierV2.GetAccount: ", err.Error()) } else if reply2.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { t.Errorf("Calling ApierV1.GetBalance received: %f", reply2.BalanceMap[utils.MONETARY].GetTotalValue()) @@ -238,7 +263,7 @@ func testCallStatMetricsBefore(t *testing.T) { utils.MetaTCC: utils.NOT_AVAILABLE, utils.MetaTCD: utils.NOT_AVAILABLE, } - if err := tutFsCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, + if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2"}, &metrics); err != nil { t.Error(err) } else if !reflect.DeepEqual(expectedMetrics, metrics) { @@ -257,7 +282,7 @@ func testCallCheckResourceBeforeAllocation(t *testing.T) { utils.Subject: "1001", utils.Destination: "1002"}, }} - if err := tutFsCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { + if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { t.Error(err) } else if len(*rs) != 2 { t.Errorf("Resources: %+v", utils.ToJSON(rs)) @@ -273,7 +298,7 @@ func testCallCheckResourceBeforeAllocation(t *testing.T) { func testCallCheckThreshold1001Before(t *testing.T) { var td engine.Threshold eTd := engine.Threshold{Tenant: "cgrates.org", ID: "THD_ACNT_1001", Hits: 0} - if err := tutFsCallsRpc.Call(utils.ThresholdSv1GetThreshold, + if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1001"}, &td); err != nil { t.Error(err) } else if !reflect.DeepEqual(eTd, td) { @@ -284,7 +309,7 @@ func testCallCheckThreshold1001Before(t *testing.T) { func testCallCheckThreshold1002Before(t *testing.T) { var td engine.Threshold eTd := engine.Threshold{Tenant: "cgrates.org", ID: "THD_ACNT_1002", Hits: 0} - if err := tutFsCallsRpc.Call(utils.ThresholdSv1GetThreshold, + if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1002"}, &td); err != nil { t.Error(err) } else if !reflect.DeepEqual(eTd, td) { @@ -303,7 +328,7 @@ func testCallStartPjsuaListener(t *testing.T) { &engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5080"}, } - if tutFsCallsPjSuaListener, err = engine.StartPjsuaListener( + if tutorialCallsPjSuaListener, err = engine.StartPjsuaListener( acnts, 5070, time.Duration(*waitRater)*time.Millisecond); err != nil { t.Fatal(err) } @@ -332,7 +357,7 @@ func testCallGetActiveSessions(t *testing.T) { Destination: "1002", }, } - if err := tutFsCallsRpc.Call(utils.SessionSv1GetActiveSessions, + if err := tutorialCallsRpc.Call(utils.SessionSv1GetActiveSessions, &map[string]string{}, &reply); err != nil { t.Error("Got error on SessionSv1.GetActiveSessions: ", err.Error()) } else { @@ -377,7 +402,7 @@ func testCallCheckResourceAllocation(t *testing.T) { utils.Subject: "1001", utils.Destination: "1002"}, }} - if err := tutFsCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { + if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { t.Error(err) } else if len(*rs) != 2 { t.Errorf("Resources: %+v", utils.ToJSON(rs)) @@ -395,7 +420,7 @@ func testCallAccount1001(t *testing.T) { time.Sleep(time.Duration(80) * time.Second) // Allow calls to finish before start querying the results var reply *engine.Account attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { + if err := tutorialCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { t.Error(err.Error()) } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() == 10.0 { // Make sure we debitted t.Errorf("Expected: 10, received: %+v", reply.BalanceMap[utils.MONETARY].GetTotalValue()) @@ -408,15 +433,12 @@ func testCallAccount1001(t *testing.T) { func testCall1001Cdrs(t *testing.T) { var reply []*engine.ExternalCDR req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { + if err := tutorialCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { t.Error("Unexpected error: ", err.Error()) } else if len(reply) != 2 { t.Error("Unexpected number of CDRs returned: ", len(reply)) } else { for _, cdr := range reply { - if cdr.Source != "freeswitch_json" && cdr.Source != "SMG_KamailioAgent" { - t.Errorf("Unexpected Source for CDR: %+v", cdr.Source) - } if cdr.RequestType != utils.META_PREPAID { t.Errorf("Unexpected RequestType for CDR: %+v", cdr.RequestType) } @@ -443,14 +465,11 @@ func testCall1001Cdrs(t *testing.T) { func testCall1002Cdrs(t *testing.T) { var reply []*engine.ExternalCDR req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1002"}, DestinationPrefixes: []string{"1001"}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { + if err := tutorialCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { t.Error("Unexpected error: ", err.Error()) } else if len(reply) != 1 { t.Error("Unexpected number of CDRs returned: ", len(reply)) } else { - if reply[0].Source != "freeswitch_json" && reply[0].Source != "SMG_KamailioAgent" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0].Source) - } if reply[0].RequestType != utils.META_POSTPAID { t.Errorf("Unexpected RequestType for CDR: %+v", reply[0].RequestType) } @@ -473,7 +492,7 @@ func testCallStatMetrics(t *testing.T) { utils.MetaTCC: "1.34009", utils.MetaTCD: "2m24s", } - if err := tutFsCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, + if err := tutorialCallsRpc.Call(utils.StatSv1GetQueueStringMetrics, &utils.TenantID{Tenant: "cgrates.org", ID: "Stats2"}, &metrics); err != nil { t.Error(err) } else if !reflect.DeepEqual(expectedMetrics1, metrics) && @@ -493,7 +512,7 @@ func testCallCheckResourceRelease(t *testing.T) { utils.Subject: "1001", utils.Destination: "1002"}, }} - if err := tutFsCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { + if err := tutorialCallsRpc.Call(utils.ResourceSv1GetResourcesForEvent, args, &rs); err != nil { t.Error(err) } else if len(*rs) != 2 { t.Errorf("Resources: %+v", rs) @@ -508,7 +527,7 @@ func testCallCheckResourceRelease(t *testing.T) { func testCallCheckThreshold1001After(t *testing.T) { var td engine.Threshold - if err := tutFsCallsRpc.Call(utils.ThresholdSv1GetThreshold, + if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1001"}, &td); err != nil && err.Error() != utils.ErrNotFound.Error() { t.Error(err) @@ -518,7 +537,7 @@ func testCallCheckThreshold1001After(t *testing.T) { func testCallCheckThreshold1002After(t *testing.T) { var td engine.Threshold eTd := engine.Threshold{Tenant: "cgrates.org", ID: "THD_ACNT_1002", Hits: 4} - if err := tutFsCallsRpc.Call(utils.ThresholdSv1GetThreshold, + if err := tutorialCallsRpc.Call(utils.ThresholdSv1GetThreshold, &utils.TenantID{Tenant: "cgrates.org", ID: "THD_ACNT_1002"}, &td); err != nil { t.Error(err) } else if !reflect.DeepEqual(eTd.Tenant, td.Tenant) { @@ -531,8 +550,8 @@ func testCallCheckThreshold1002After(t *testing.T) { } func testCallStopPjsuaListener(t *testing.T) { - tutFsCallsPjSuaListener.Write([]byte("q\n")) // Close pjsua - time.Sleep(time.Duration(1) * time.Second) // Allow pjsua to finish it's tasks, eg un-REGISTER + tutorialCallsPjSuaListener.Write([]byte("q\n")) // Close pjsua + time.Sleep(time.Duration(1) * time.Second) // Allow pjsua to finish it's tasks, eg un-REGISTER } func testCallStopCgrEngine(t *testing.T) { @@ -548,5 +567,7 @@ func testCallStopFS(t *testing.T) { engine.KillProcName(utils.Kamailio, 1000) } else if optConf == utils.Opensips { engine.KillProcName(utils.Opensips, 1000) + } else if optConf == utils.Asterisk { + engine.KillProcName(utils.Asterisk, 1000) } } diff --git a/general_tests/tutorial_fs_calls_test.go b/general_tests/tutorial_fs_calls_test.go deleted file mode 100644 index 4bcd8987c..000000000 --- a/general_tests/tutorial_fs_calls_test.go +++ /dev/null @@ -1,497 +0,0 @@ -// +build calls - -/* -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 -*/ - -package general_tests - -import ( - "net/rpc" - "net/rpc/jsonrpc" - "os" - "path" - "reflect" - "testing" - "time" - - "github.com/cgrates/cgrates/apier/v1" - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var tutFsCallsCfg *config.CGRConfig -var tutFsCallsRpc *rpc.Client -var tutFsCallsPjSuaListener *os.File - -func TestTutFsCallsInitCfg(t *testing.T) { - // Init config first - var err error - tutFsCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*dataDir, "tutorials", "fs_evsock", "cgrates", "etc", "cgrates")) - if err != nil { - t.Error(err) - } - tutFsCallsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() - config.SetCgrConfig(tutFsCallsCfg) -} - -// Remove data in both rating and accounting db -func TestTutFsCallsResetDataDb(t *testing.T) { - if err := engine.InitDataDb(tutFsCallsCfg); err != nil { - t.Fatal(err) - } -} - -// Wipe out the cdr database -func TestTutFsCallsResetStorDb(t *testing.T) { - if err := engine.InitStorDb(tutFsCallsCfg); err != nil { - t.Fatal(err) - } -} - -// start FS server -func TestTutFsCallsStartFS(t *testing.T) { - engine.KillProcName("freeswitch", 5000) - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "fs_evsock", "freeswitch", "etc", "init.d", "freeswitch"), "start", 3000); err != nil { - t.Fatal(err) - } -} - -// Start CGR Engine -func TestTutFsCallsStartEngine(t *testing.T) { - engine.KillProcName("cgr-engine", *waitRater) - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "fs_evsock", "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { - t.Fatal(err) - } -} - -// Restart FS so we make sure reconnects are working -func TestTutFsCallsRestartFS(t *testing.T) { - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "fs_evsock", "freeswitch", "etc", "init.d", "freeswitch"), "restart", 5000); err != nil { - t.Fatal(err) - } -} - -// Connect rpc client to rater -func TestTutFsCallsRpcConn(t *testing.T) { - var err error - tutFsCallsRpc, err = jsonrpc.Dial("tcp", tutFsCallsCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -// Load the tariff plan, creating accounts and their balances -func TestTutFsCallsLoadTariffPlanFromFolder(t *testing.T) { - reply := "" - attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} - if err := tutFsCallsRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { - t.Error(err) - } else if reply != "OK" { - t.Error(reply) - } - time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups -} - -// Make sure account was debited properly -func TestTutFsCallsAccountsBefore(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1002"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1003"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1004"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1007"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 0.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1005"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Errorf("Got error on ApierV2.GetAccount: %v", err) - } -} - -// Make sure all stats queues are in place -func TestTutFsCallsCdrStatsBefore(t *testing.T) { - //eQueueIds := []string{"*default", "CDRST1", "CDRST_1001", "CDRST_1002", "CDRST_1003", "STATS_SUPPL1", "STATS_SUPPL2"} - var statMetrics map[string]float64 - eMetrics := map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutFsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST1"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACC: -1, engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1} - if err := tutFsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1001"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutFsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1002"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutFsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1003"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutFsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL1"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutFsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL2"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } -} - -// Start Pjsua as listener and register it to receive calls -func TestTutFsCallsStartPjsuaListener(t *testing.T) { - var err error - acnts := []*engine.PjsuaAccount{ - &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1004@127.0.0.1", Username: "1004", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1006@127.0.0.1", Username: "1006", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1007@127.0.0.1", Username: "1007", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}} - if tutFsCallsPjSuaListener, err = engine.StartPjsuaListener(acnts, 5070, time.Duration(*waitRater)*time.Millisecond); err != nil { - t.Fatal(err) - } -} - -// Call from 1001 (prepaid) to 1002 -func TestTutFsCallsCall1001To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "1234", Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(67)*time.Second, 5071); err != nil { - t.Fatal(err) - } -} - -// Call from 1001 (prepaid) to 1003 -func TestTutFsCallsCall1001To1003(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "1234", Realm: "*"}, "sip:1003@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(65)*time.Second, 5072); err != nil { - t.Fatal(err) - } -} - -func TestTutFsCallsCall1002To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: "1234", Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(61)*time.Second, 5073); err != nil { - t.Fatal(err) - } -} - -func TestTutFsCallsCall1003To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "1234", Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(63)*time.Second, 5074); err != nil { - t.Fatal(err) - } -} - -func TestTutFsCallsCall1004To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1004@127.0.0.1", Username: "1004", Password: "1234", Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(62)*time.Second, 5075); err != nil { - t.Fatal(err) - } -} - -func TestTutFsCallsCall1006To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1006@127.0.0.1", Username: "1006", Password: "1234", Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(64)*time.Second, 5076); err != nil { - t.Fatal(err) - } -} - -func TestTutFsCallsCall1007To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1007@127.0.0.1", Username: "1007", Password: "1234", Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(66)*time.Second, 5077); err != nil { - t.Fatal(err) - } -} - -// Make sure account was debited properly -func TestTutFsCallsAccount1001(t *testing.T) { - time.Sleep(time.Duration(80) * time.Second) // Allow calls to finish before start querying the results - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() == 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } else if reply.Disabled == true { - t.Error("Account disabled") - } -} - -// Make sure account was debited properly -func TestTutFsCalls1001Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - //var CGRID string // Share with getCostDetails - //var cCost engine.CallCost - req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}, DestinationPrefixes: []string{"1002"}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - //CGRID = reply[0].CGRID - if reply[0].Source != "freeswitch_json" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Usage != "67" && reply[0].Usage != "68" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost == -1.0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - //if reply[0].Supplier != "suppl2" { // Usage as seconds - // t.Errorf("Unexpected Supplier for CDR: %+v", reply[0]) - //} - } - /* - // Make sure call cost contains the matched information - if err := tutFsCallsRpc.Call("ApierV2.GetCallCostLog", utils.AttrGetCallCost{CgrId: CGRID}, &cCost); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if utils.IsSliceMember([]string{cCost.Timespans[0].MatchedSubject, cCost.Timespans[0].MatchedPrefix, cCost.Timespans[0].MatchedDestId}, "") { - t.Errorf("Unexpected Matched* for CallCost: %+v", cCost.Timespans[0]) - } - */ - - req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}, DestinationPrefixes: []string{"1003"}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - //CGRID = reply[0].CGRID - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Usage != "65" && reply[0].Usage != "66" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost != 0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - } - /* - // Make sure call cost contains the matched information - if err := tutFsCallsRpc.Call("ApierV2.GetCallCostLog", utils.AttrGetCallCost{CgrId: CGRID}, &cCost); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if utils.IsSliceMember([]string{cCost.Timespans[0].MatchedSubject, cCost.Timespans[0].MatchedPrefix, cCost.Timespans[0].MatchedDestId}, "") { - t.Errorf("Unexpected Matched* for CallCost: %+v", cCost.Timespans[0]) - } - */ - req = utils.RPCCDRsFilter{Accounts: []string{"1001"}, RunIDs: []string{"derived_run1"}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].RequestType != utils.META_RATED { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Subject != "1002" { - t.Errorf("Unexpected Subject for CDR: %+v", reply[0]) - } - } - -} - -// Make sure account was debited properly -func TestTutFsCalls1002Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1002"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { // Should be counted here also call originated form 1006 which is aliased to 1002 - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "freeswitch_json" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_POSTPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "61" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } -} - -// Make sure account was debited properly -func TestTutFsCalls1003Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1003"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "freeswitch_json" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PSEUDOPREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "63" && reply[0].Usage != "64" { // Usage as seconds, sometimes takes a second longer to disconnect - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } - -} - -// Make sure account was debited properly -func TestTutFsCalls1004Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1004"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "freeswitch_json" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_RATED { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "62" && reply[0].Usage != "63" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } - -} - -// Make sure we don't have any CDRs for 1006 since it should have been aliased to 1002 -func TestTutFsCalls1006Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1006"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 0 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } -} - -// Make sure account was debited properly -func TestTutFsCalls1007Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1007"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutFsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "freeswitch_json" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1002" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "66" && reply[0].Usage != "67" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost == -1.0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - } -} - -// Make sure account was debited properly -func TestTutFsCallsAccountFraud1001(t *testing.T) { - var reply string - attrAddBlnc := &v1.AttrAddBalance{Tenant: "cgrates.org", Account: "1001", BalanceType: "*monetary", Value: 101} - if err := tutFsCallsRpc.Call("ApierV1.AddBalance", attrAddBlnc, &reply); err != nil { - t.Error("Got error on ApierV1.AddBalance: ", err.Error()) - } else if reply != "OK" { - t.Errorf("Calling ApierV1.AddBalance received: %s", reply) - } -} - -// Based on Fraud automatic mitigation, our account should be disabled -func TestTutFsCallsAccountDisabled1001(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutFsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.Disabled == false { - t.Error("Account should be disabled per fraud detection rules.") - } -} - -func TestTutFsCallsStopPjsuaListener(t *testing.T) { - tutFsCallsPjSuaListener.Write([]byte("q\n")) // Close pjsua - time.Sleep(time.Duration(1) * time.Second) // Allow pjsua to finish it's tasks, eg un-REGISTER -} - -func TestTutFsCallsStopCgrEngine(t *testing.T) { - if err := engine.KillEngine(100); err != nil { - t.Error(err) - } -} - -func TestTutFsCallsStopFS(t *testing.T) { - engine.KillProcName("freeswitch", 1000) -} diff --git a/general_tests/tutorial_kam_calls_test.go b/general_tests/tutorial_kam_calls_test.go deleted file mode 100644 index 0254d2e12..000000000 --- a/general_tests/tutorial_kam_calls_test.go +++ /dev/null @@ -1,496 +0,0 @@ -// +build calls - -/* -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 -*/ - -package general_tests - -import ( - "net/rpc" - "net/rpc/jsonrpc" - "os" - "path" - "reflect" - "testing" - "time" - - "github.com/cgrates/cgrates/apier/v1" - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var tutKamCallsCfg *config.CGRConfig -var tutKamCallsRpc *rpc.Client -var tutKamCallsPjSuaListener *os.File - -func TestTutKamCallsInitCfg(t *testing.T) { - // Init config first - var err error - tutKamCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*dataDir, "tutorials", "kamevapi", "cgrates", "etc", "cgrates")) - if err != nil { - t.Error(err) - } - tutKamCallsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() - config.SetCgrConfig(tutKamCallsCfg) -} - -// Remove data in both rating and accounting db -func TestTutKamCallsResetDataDb(t *testing.T) { - if err := engine.InitDataDb(tutKamCallsCfg); err != nil { - t.Fatal(err) - } -} - -// Wipe out the cdr database -func TestTutKamCallsResetStorDb(t *testing.T) { - if err := engine.InitStorDb(tutKamCallsCfg); err != nil { - t.Fatal(err) - } -} - -// start FS server -func TestTutKamCallsStartKamailio(t *testing.T) { - engine.KillProcName("kamailio", 3000) - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "kamevapi", "kamailio", "etc", "init.d", "kamailio"), "start", 2000); err != nil { - t.Fatal(err) - } -} - -// Start CGR Engine -func TestTutKamCallsStartEngine(t *testing.T) { - engine.KillProcName("cgr-engine", *waitRater) - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "kamevapi", "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { - t.Fatal(err) - } -} - -// Restart FS so we make sure reconnects are working -func TestTutKamCallsRestartKamailio(t *testing.T) { - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "kamevapi", "kamailio", "etc", "init.d", "kamailio"), "restart", 3000); err != nil { - t.Fatal(err) - } -} - -// Connect rpc client to rater -func TestTutKamCallsRpcConn(t *testing.T) { - var err error - tutKamCallsRpc, err = jsonrpc.Dial("tcp", tutKamCallsCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -// Load the tariff plan, creating accounts and their balances -func TestTutKamCallsLoadTariffPlanFromFolder(t *testing.T) { - reply := "" - attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} - if err := tutKamCallsRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { - t.Error(err) - } else if reply != "OK" { - t.Error(reply) - } - time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups -} - -// Make sure account was debited properly -func TestTutKamCallsAccountsBefore(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutKamCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1002"} - if err := tutKamCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1003"} - if err := tutKamCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1004"} - if err := tutKamCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1007"} - if err := tutKamCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 0.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1005"} - if err := tutKamCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Errorf("Got error on ApierV2.GetAccount: %v", err) - } -} - -// Make sure all stats queues are in place -func TestTutKamCallsCdrStatsBefore(t *testing.T) { - //eQueueIds := []string{"*default", "CDRST1", "CDRST_1001", "CDRST_1002", "CDRST_1003", "STATS_SUPPL1", "STATS_SUPPL2"} - var statMetrics map[string]float64 - eMetrics := map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST1"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACC: -1, engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1} - if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1001"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1002"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1003"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL1"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL2"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } -} - -// Start Pjsua as listener and register it to receive calls -func TestTutKamCallsStartPjsuaListener(t *testing.T) { - var err error - acnts := []*engine.PjsuaAccount{ - &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1004@127.0.0.1", Username: "1004", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1006@127.0.0.1", Username: "1006", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1007@127.0.0.1", Username: "1007", Password: "CGRateS.org", Realm: "*", Registrar: "sip:127.0.0.1:5060"}} - if tutKamCallsPjSuaListener, err = engine.StartPjsuaListener(acnts, 5070, time.Duration(*waitRater)*time.Millisecond); err != nil { - t.Fatal(err) - } -} - -// Call from 1001 (prepaid) to 1002 -func TestTutKamCallsCall1001To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(67)*time.Second, 5071); err != nil { - t.Fatal(err) - } -} - -// Call from 1001 (prepaid) to 1003 -func TestTutKamCallsCall1001To1003(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, "sip:1003@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(65)*time.Second, 5072); err != nil { - t.Fatal(err) - } -} - -func TestTutKamCallsCall1002To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: "CGRateS.org", Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(61)*time.Second, 5073); err != nil { - t.Fatal(err) - } -} - -func TestTutKamCallsCall1003To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "CGRateS.org", Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(63)*time.Second, 5074); err != nil { - t.Fatal(err) - } -} - -func TestTutKamCallsCall1004To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1004@127.0.0.1", Username: "1004", Password: "CGRateS.org", Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(62)*time.Second, 5075); err != nil { - t.Fatal(err) - } -} - -func TestTutKamCallsCall1006To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1006@127.0.0.1", Username: "1006", Password: "CGRateS.org", Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(64)*time.Second, 5076); err != nil { - t.Fatal(err) - } -} - -func TestTutKamCallsCall1007To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1007@127.0.0.1", Username: "1007", Password: "CGRateS.org", Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(66)*time.Second, 5077); err != nil { - t.Fatal(err) - } -} - -// Make sure account was debited properly -func TestTutKamCallsAccount1001(t *testing.T) { - time.Sleep(time.Duration(70) * time.Second) // Allow calls to finish before start querying the results - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutKamCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() == 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } else if reply.Disabled == true { - t.Error("Account disabled") - } -} - -// Make sure account was debited properly -func TestTutKamCalls1001Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - //var cgrId string // Share with getCostDetails - //var cCost engine.CallCost - req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}, DestinationPrefixes: []string{"1002"}} - if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - //cgrId = reply[0].CGRID - if reply[0].Source != "KAMAILIO_CGR_CALL_END" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Usage != "67" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost == -1.0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - //if reply[0].Supplier != "suppl2" { // Usage as seconds - // t.Errorf("Unexpected Supplier for CDR: %+v", reply[0]) - //} - } - /* - // Make sure call cost contains the matched information - if err := tutKamCallsRpc.Call("ApierV2.GetCallCostLog", utils.AttrGetCallCost{CgrId: cgrId}, &cCost); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if utils.IsSliceMember([]string{cCost.Timespans[0].MatchedSubject, cCost.Timespans[0].MatchedPrefix, cCost.Timespans[0].MatchedDestId}, "") { - t.Errorf("Unexpected Matched* for CallCost: %+v", cCost.Timespans[0]) - } - */ - req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}, DestinationPrefixes: []string{"1003"}} - if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - //cgrId = reply[0].CGRID - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Usage != "65" && reply[0].Usage != "66" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost != 0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - } - /* - // Make sure call cost contains the matched information - if err := tutKamCallsRpc.Call("ApierV2.GetCallCostLog", utils.AttrGetCallCost{CgrId: cgrId}, &cCost); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if utils.IsSliceMember([]string{cCost.Timespans[0].MatchedSubject, cCost.Timespans[0].MatchedPrefix, cCost.Timespans[0].MatchedDestId}, "") { - t.Errorf("Unexpected Matched* for CallCost: %+v", cCost.Timespans[0]) - } - */ - req = utils.RPCCDRsFilter{Accounts: []string{"1001"}, RunIDs: []string{"derived_run1"}} - if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].RequestType != utils.META_RATED { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Subject != "1002" { - t.Errorf("Unexpected Subject for CDR: %+v", reply[0]) - } - } - -} - -// Make sure account was debited properly -func TestTutKamCalls1002Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1002"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "KAMAILIO_CGR_CALL_END" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_POSTPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "61" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } -} - -// Make sure account was debited properly -func TestTutKamCalls1003Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1003"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "KAMAILIO_CGR_CALL_END" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PSEUDOPREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "63" && reply[0].Usage != "64" { // Usage as seconds, sometimes takes a second longer to disconnect - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } - -} - -// Make sure account was debited properly -func TestTutKamCalls1004Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1004"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "KAMAILIO_CGR_CALL_END" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_RATED { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "62" && reply[0].Usage != "63" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } - -} - -// Make sure account was debited properly -func TestTutKamCalls1006Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1006"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 0 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } -} - -// Make sure account was debited properly -func TestTutKamCalls1007Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1007"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "KAMAILIO_CGR_CALL_END" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1002" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "66" && reply[0].Usage != "67" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost == -1.0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - } -} - -// Make sure account was debited properly -func TestTutKamCallsAccountFraud1001(t *testing.T) { - var reply string - attrAddBlnc := &v1.AttrAddBalance{Tenant: "cgrates.org", Account: "1001", BalanceType: "*monetary", Value: 101} - if err := tutKamCallsRpc.Call("ApierV1.AddBalance", attrAddBlnc, &reply); err != nil { - t.Error("Got error on ApierV1.AddBalance: ", err.Error()) - } else if reply != "OK" { - t.Errorf("Calling ApierV1.AddBalance received: %s", reply) - } -} - -// Based on Fraud automatic mitigation, our account should be disabled -func TestTutKamCallsAccountDisabled1001(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutKamCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.Disabled == false { - t.Error("Account should be disabled per fraud detection rules.") - } -} - -func TestTutKamCallsStopPjsuaListener(t *testing.T) { - tutKamCallsPjSuaListener.Write([]byte("q\n")) // Close pjsua - time.Sleep(time.Duration(1) * time.Second) // Allow pjsua to finish it's tasks, eg un-REGISTER -} - -func TestTutKamCallsStopCgrEngine(t *testing.T) { - if err := engine.KillEngine(100); err != nil { - t.Error(err) - } -} - -func TestTutKamCallsStopKam(t *testing.T) { - engine.KillProcName("kamailio", 1000) -} diff --git a/general_tests/tutorial_osips_calls_test.go b/general_tests/tutorial_osips_calls_test.go deleted file mode 100644 index ca8c8ef47..000000000 --- a/general_tests/tutorial_osips_calls_test.go +++ /dev/null @@ -1,496 +0,0 @@ -// +build calls - -/* -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 -*/ - -package general_tests - -import ( - "net/rpc" - "net/rpc/jsonrpc" - "os" - "path" - "reflect" - "testing" - "time" - - "github.com/cgrates/cgrates/apier/v1" - "github.com/cgrates/cgrates/config" - "github.com/cgrates/cgrates/engine" - "github.com/cgrates/cgrates/utils" -) - -var tutOsipsCallsCfg *config.CGRConfig -var tutOsipsCallsRpc *rpc.Client -var tutOsipsCallsPjSuaListener *os.File - -func TestTutOsipsCallsInitCfg(t *testing.T) { - // Init config first - var err error - tutOsipsCallsCfg, err = config.NewCGRConfigFromFolder(path.Join(*dataDir, "tutorials", "osips_async", "cgrates", "etc", "cgrates")) - if err != nil { - t.Error(err) - } - tutOsipsCallsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() - config.SetCgrConfig(tutOsipsCallsCfg) -} - -// Remove data in both rating and accounting db -func TestTutOsipsCallsResetDataDb(t *testing.T) { - if err := engine.InitDataDb(tutOsipsCallsCfg); err != nil { - t.Fatal(err) - } -} - -// Wipe out the cdr database -func TestTutOsipsCallsResetStorDb(t *testing.T) { - if err := engine.InitStorDb(tutOsipsCallsCfg); err != nil { - t.Fatal(err) - } -} - -// start FS server -func TestTutOsipsCallsStartOsips(t *testing.T) { - engine.KillProcName("opensips", 3000) - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "osips_async", "opensips", "etc", "init.d", "opensips"), "start", 3000); err != nil { - t.Fatal(err) - } -} - -// Start CGR Engine -func TestTutOsipsCallsStartEngine(t *testing.T) { - engine.KillProcName("cgr-engine", *waitRater) - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "osips_async", "cgrates", "etc", "init.d", "cgrates"), "start", 100); err != nil { - t.Fatal(err) - } -} - -// Restart FS so we make sure reconnects are working -func TestTutOsipsCallsRestartOsips(t *testing.T) { - if err := engine.CallScript(path.Join(*dataDir, "tutorials", "osips_async", "opensips", "etc", "init.d", "opensips"), "restart", 3000); err != nil { - t.Fatal(err) - } -} - -// Connect rpc client to rater -func TestTutOsipsCallsRpcConn(t *testing.T) { - var err error - tutOsipsCallsRpc, err = jsonrpc.Dial("tcp", tutOsipsCallsCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed - if err != nil { - t.Fatal(err) - } -} - -// Load the tariff plan, creating accounts and their balances -func TestTutOsipsCallsLoadTariffPlanFromFolder(t *testing.T) { - reply := "" - attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} - if err := tutOsipsCallsRpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { - t.Error(err) - } else if reply != "OK" { - t.Error(reply) - } - time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups -} - -// Make sure account was debited properly -func TestTutOsipsCallsAccountsBefore(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutOsipsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1002"} - if err := tutOsipsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1003"} - if err := tutOsipsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1004"} - if err := tutOsipsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1007"} - if err := tutOsipsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() != 0.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } - attrs = &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1005"} - if err := tutOsipsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { - t.Error("Got error on ApierV2.GetAccount: %v", err) - } -} - -// Make sure all stats queues are in place -func TestTutOsipsCallsCdrStatsBefore(t *testing.T) { - //eQueueIds := []string{"*default", "CDRST1", "CDRST_1001", "CDRST_1002", "CDRST_1003", "STATS_SUPPL1", "STATS_SUPPL2"} - var statMetrics map[string]float64 - eMetrics := map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutOsipsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST1"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACC: -1, engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1} - if err := tutOsipsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1001"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutOsipsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1002"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutOsipsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1003"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutOsipsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL1"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } - eMetrics = map[string]float64{engine.ACD: -1, engine.ASR: -1, engine.TCC: -1, engine.TCD: -1, engine.ACC: -1} - if err := tutOsipsCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL2"}, &statMetrics); err != nil { - t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) - } else if !reflect.DeepEqual(eMetrics, statMetrics) { - t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) - } -} - -// Start Pjsua as listener and register it to receive calls -func TestTutOsipsCallsStartPjsuaListener(t *testing.T) { - var err error - acnts := []*engine.PjsuaAccount{ - &engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1004@127.0.0.1", Username: "1004", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1006@127.0.0.1", Username: "1006", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}, - &engine.PjsuaAccount{Id: "sip:1007@127.0.0.1", Username: "1007", Password: "1234", Realm: "*", Registrar: "sip:127.0.0.1:5060"}} - if tutOsipsCallsPjSuaListener, err = engine.StartPjsuaListener(acnts, 5070, time.Duration(*waitRater)*time.Millisecond); err != nil { - t.Fatal(err) - } -} - -// Call from 1001 (prepaid) to 1002 -func TestTutOsipsCallsCall1001To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "1234", Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(67)*time.Second, 5071); err != nil { - t.Fatal(err) - } -} - -// Call from 1001 (prepaid) to 1003 -func TestTutOsipsCallsCall1001To1003(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "1234", Realm: "*"}, "sip:1003@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(65)*time.Second, 5072); err != nil { - t.Fatal(err) - } -} - -func TestTutOsipsCallsCall1002To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1002@127.0.0.1", Username: "1002", Password: "1234", Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(61)*time.Second, 5073); err != nil { - t.Fatal(err) - } -} - -func TestTutOsipsCallsCall1003To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "1234", Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(63)*time.Second, 5074); err != nil { - t.Fatal(err) - } -} - -func TestTutOsipsCallsCall1004To1001(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1004@127.0.0.1", Username: "1004", Password: "1234", Realm: "*"}, "sip:1001@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(62)*time.Second, 5075); err != nil { - t.Fatal(err) - } -} - -func TestTutOsipsCallsCall1006To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1006@127.0.0.1", Username: "1006", Password: "1234", Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(64)*time.Second, 5076); err != nil { - t.Fatal(err) - } -} - -func TestTutOsipsCallsCall1007To1002(t *testing.T) { - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1007@127.0.0.1", Username: "1007", Password: "1234", Realm: "*"}, "sip:1002@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(66)*time.Second, 5077); err != nil { - t.Fatal(err) - } -} - -// Make sure account was debited properly -func TestTutOsipsCallsAccount1001(t *testing.T) { - time.Sleep(time.Duration(70) * time.Second) // Allow calls to finish before start querying the results - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutOsipsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.BalanceMap[utils.MONETARY].GetTotalValue() == 10.0 { // Make sure we debitted - t.Errorf("Calling ApierV1.GetBalance received: %f", reply.BalanceMap[utils.MONETARY].GetTotalValue()) - } else if reply.Disabled == true { - t.Error("Account disabled") - } -} - -// Make sure account was debited properly -func TestTutOsipsCalls1001Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - //var cgrId string // Share with getCostDetails - //var cCost engine.CallCost - req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}, DestinationPrefixes: []string{"1002"}} - if err := tutOsipsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - //cgrId = reply[0].CGRID - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Usage != "67" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost == -1.0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - //if reply[0].Supplier != "suppl2" { // Usage as seconds - // t.Errorf("Unexpected Supplier for CDR: %+v", reply[0]) - //} - } - /* - // Make sure call cost contains the matched information - if err := tutOsipsCallsRpc.Call("ApierV2.GetCallCostLog", utils.AttrGetCallCost{CgrId: cgrId}, &cCost); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if utils.IsSliceMember([]string{cCost.Timespans[0].MatchedSubject, cCost.Timespans[0].MatchedPrefix, cCost.Timespans[0].MatchedDestId}, "") { - t.Errorf("Unexpected Matched* for CallCost: %+v", cCost.Timespans[0]) - } - */ - req = utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, Accounts: []string{"1001"}, DestinationPrefixes: []string{"1003"}} - if err := tutOsipsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - //cgrId = reply[0].CGRID - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Usage != "65" && reply[0].Usage != "66" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost != 0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - } - /* - // Make sure call cost contains the matched information - if err := tutOsipsCallsRpc.Call("ApierV2.GetCallCostLog", utils.AttrGetCallCost{CgrId: cgrId}, &cCost); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if utils.IsSliceMember([]string{cCost.Timespans[0].MatchedSubject, cCost.Timespans[0].MatchedPrefix, cCost.Timespans[0].MatchedDestId}, "") { - t.Errorf("Unexpected Matched* for CallCost: %+v", cCost.Timespans[0]) - } - */ - req = utils.RPCCDRsFilter{Accounts: []string{"1001"}, RunIDs: []string{"derived_run1"}} - if err := tutOsipsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].RequestType != utils.META_RATED { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Subject != "1002" { - t.Errorf("Unexpected Subject for CDR: %+v", reply[0]) - } - } - -} - -// Make sure account was debited properly -func TestTutOsipsCalls1002Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1002"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutOsipsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 2 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_POSTPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "61" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } -} - -// Make sure account was debited properly -func TestTutOsipsCalls1003Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1003"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutOsipsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PSEUDOPREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "63" && reply[0].Usage != "64" { // Usage as seconds, sometimes takes a second longer to disconnect - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } - -} - -// Make sure account was debited properly -func TestTutOsipsCalls1004Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1004"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutOsipsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_RATED { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1001" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "62" && reply[0].Usage != "63" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - } - -} - -// Make sure aliasing was done for 1006 and we have no CDRs for it -func TestTutOsipsCalls1006Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1006"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutOsipsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 0 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } -} - -// Make sure account was debited properly -func TestTutOsipsCalls1007Cdrs(t *testing.T) { - var reply []*engine.ExternalCDR - req := utils.RPCCDRsFilter{Accounts: []string{"1007"}, RunIDs: []string{utils.META_DEFAULT}} - if err := tutOsipsCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { - t.Error("Unexpected number of CDRs returned: ", len(reply)) - } else { - if reply[0].Source != "OSIPS_E_ACC_EVENT" { - t.Errorf("Unexpected Source for CDR: %+v", reply[0]) - } - if reply[0].RequestType != utils.META_PREPAID { - t.Errorf("Unexpected RequestType for CDR: %+v", reply[0]) - } - if reply[0].Destination != "1002" { - t.Errorf("Unexpected Destination for CDR: %+v", reply[0]) - } - if reply[0].Usage != "66" && reply[0].Usage != "67" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) - } - if reply[0].Cost == -1.0 { // Cost was not calculated - t.Errorf("Unexpected Cost for CDR: %+v", reply[0]) - } - } -} - -// Make sure account was debited properly -func TestTutOsipsCallsAccountFraud1001(t *testing.T) { - var reply string - attrAddBlnc := &v1.AttrAddBalance{Tenant: "cgrates.org", Account: "1001", BalanceType: "*monetary", Value: 101} - if err := tutOsipsCallsRpc.Call("ApierV1.AddBalance", attrAddBlnc, &reply); err != nil { - t.Error("Got error on ApierV1.AddBalance: ", err.Error()) - } else if reply != "OK" { - t.Errorf("Calling ApierV1.AddBalance received: %s", reply) - } -} - -// Based on Fraud automatic mitigation, our account should be disabled -func TestTutOsipsCallsAccountDisabled1001(t *testing.T) { - var reply *engine.Account - attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} - if err := tutOsipsCallsRpc.Call("ApierV2.GetAccount", attrs, &reply); err != nil { - t.Error("Got error on ApierV2.GetAccount: ", err.Error()) - } else if reply.Disabled == false { - t.Error("Account should be disabled per fraud detection rules.") - } -} - -func TestTutOsipsCallsStopPjsuaListener(t *testing.T) { - tutOsipsCallsPjSuaListener.Write([]byte("q\n")) // Close pjsua - time.Sleep(time.Duration(1) * time.Second) // Allow pjsua to finish it's tasks, eg un-REGISTER -} - -func TestTutOsipsCallsStopCgrEngine(t *testing.T) { - if err := engine.KillEngine(100); err != nil { - t.Error(err) - } -} - -func TestTutOsipsCallsStopOpensips(t *testing.T) { - engine.KillProcName("opensips", 100) -} diff --git a/utils/consts.go b/utils/consts.go index ac55ac920..d57bf32eb 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -535,6 +535,7 @@ const ( Freeswitch = "freeswitch" Kamailio = "kamailio" Opensips = "opensips" + Asterisk = "asterisk" ) // Migrator Action