From 8af6f61bb5048b59bf84fc21b69427e510ad9bbc Mon Sep 17 00:00:00 2001 From: DanB Date: Sat, 14 Nov 2015 18:56:14 +0100 Subject: [PATCH] New agents package, ListenAndServe for DiameterAgent, integration tests, adding fiorix/go-diameter in the list of dependencies --- agents/dmtagent.go | 63 +++++++++++++++++ agents/dmtagent_it_test.go | 89 +++++++++++++++++++++++++ cmd/cgr-engine/cgr-engine.go | 35 +++++++++- config/config.go | 21 +++--- config/config_defaults.go | 10 ++- config/config_json_test.go | 16 +++-- config/daconfig.go | 16 +++++ config/libconfig_json.go | 4 ++ data/conf/samples/dmtagent/cgrates.json | 82 +++++++++++++++++++++++ devel.yaml | 1 + glide.yaml | 6 +- test.sh | 6 +- utils/consts.go | 1 + 13 files changed, 327 insertions(+), 23 deletions(-) create mode 100644 agents/dmtagent.go create mode 100644 agents/dmtagent_it_test.go create mode 100644 data/conf/samples/dmtagent/cgrates.json diff --git a/agents/dmtagent.go b/agents/dmtagent.go new file mode 100644 index 000000000..88379ef54 --- /dev/null +++ b/agents/dmtagent.go @@ -0,0 +1,63 @@ +/* +Real-time Charging System for Telecom & ISP environments +Copyright (C) 2012-2015 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 agents + +import ( + "fmt" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" + "github.com/fiorix/go-diameter/diam" + //"github.com/fiorix/go-diameter/diam/avp" + "github.com/fiorix/go-diameter/diam/datatype" + //"github.com/fiorix/go-diameter/diam/dict" + "github.com/fiorix/go-diameter/diam/sm" +) + +func NewDiameterAgent(cgrCfg *config.CGRConfig, smg *rpcclient.RpcClient) *DiameterAgent { + return &DiameterAgent{cgrCfg: cgrCfg, smg: smg} +} + +type DiameterAgent struct { + cgrCfg *config.CGRConfig + smg *rpcclient.RpcClient // Connection towards CGR-SMG component +} + +// Creates the message handlers +func (self *DiameterAgent) handlers() diam.Handler { + settings := &sm.Settings{ + OriginHost: datatype.DiameterIdentity(self.cgrCfg.DiameterAgentCfg().OriginHost), + OriginRealm: datatype.DiameterIdentity(self.cgrCfg.DiameterAgentCfg().OriginRealm), + VendorID: datatype.Unsigned32(self.cgrCfg.DiameterAgentCfg().VendorId), + ProductName: datatype.UTF8String(self.cgrCfg.DiameterAgentCfg().ProductName), + FirmwareRevision: datatype.Unsigned32(utils.DIAMETER_FIRMWARE_REVISION), + } + dSM := sm.New(settings) + dSM.HandleFunc("ALL", self.handleALL) + return dSM +} + +func (self *DiameterAgent) handleALL(c diam.Conn, m *diam.Message) { + utils.Logger.Warning(fmt.Sprintf(" Received unexpected message from %s:\n%s", c.RemoteAddr(), m)) +} + +func (self *DiameterAgent) ListenAndServe() error { + return diam.ListenAndServe(self.cgrCfg.DiameterAgentCfg().Listen, self.handlers(), nil) +} diff --git a/agents/dmtagent_it_test.go b/agents/dmtagent_it_test.go new file mode 100644 index 000000000..195651647 --- /dev/null +++ b/agents/dmtagent_it_test.go @@ -0,0 +1,89 @@ +/* +Real-time Charging System for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can Storagetribute 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 WITH*out 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 agents + +import ( + "flag" + "path" + "testing" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" +) + +var testIntegration = flag.Bool("integration", false, "Perform the tests in integration mode, not by default.") // This flag will be passed here via "go test -local" args +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 daCfgPath string +var daCfg *config.CGRConfig + +func TestDmtAgentInitCfg(t *testing.T) { + if !*testIntegration { + return + } + daCfgPath = path.Join(*dataDir, "conf", "samples", "dmtagent") + // Init config first + var err error + daCfg, err = config.NewCGRConfigFromFolder(daCfgPath) + if err != nil { + t.Error(err) + } + daCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() + config.SetCgrConfig(daCfg) +} + +// Remove data in both rating and accounting db +func TestDmtAgentResetDataDb(t *testing.T) { + if !*testIntegration { + return + } + if err := engine.InitDataDb(daCfg); err != nil { + t.Fatal(err) + } +} + +// Wipe out the cdr database +func TestDmtAgentResetStorDb(t *testing.T) { + if !*testIntegration { + return + } + if err := engine.InitStorDb(daCfg); err != nil { + t.Fatal(err) + } +} + +// Start CGR Engine +func TestDmtAgentStartEngine(t *testing.T) { + if !*testIntegration { + return + } + if _, err := engine.StopStartEngine(daCfgPath, *waitRater); err != nil { + t.Fatal(err) + } +} + +func TestDmtAgentStopEngine(t *testing.T) { + if !*testIntegration { + return + } + if err := engine.KillEngine(*waitRater); err != nil { + t.Error(err) + } +} diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index bda3b2047..fcee44ef4 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -29,6 +29,7 @@ import ( "strconv" "time" + "github.com/cgrates/cgrates/agents" "github.com/cgrates/cgrates/apier/v1" "github.com/cgrates/cgrates/apier/v2" "github.com/cgrates/cgrates/balancer2go" @@ -135,7 +136,7 @@ func startCdrc(internalCdrSChan chan *engine.CdrServer, internalRaterChan chan * } } -func startSmGeneric(internalRaterChan chan *engine.Responder, server *utils.Server, exitChan chan bool) { +func startSmGeneric(internalSMGChan chan rpcclient.RpcClientConnection, internalRaterChan chan *engine.Responder, server *utils.Server, exitChan chan bool) { utils.Logger.Info("Starting CGRateS SM-Generic service.") var raterConn, cdrsConn engine.Connector var client *rpcclient.RpcClient @@ -184,6 +185,7 @@ func startSmGeneric(internalRaterChan chan *engine.Responder, server *utils.Serv // Register RPC handler smgRpc := v1.NewSMGenericV1(sm) server.RpcRegister(smgRpc) + internalSMGChan <- smgRpc // Register BiRpc handlers smgBiRpc := v1.NewSMGenericBiRpcV1(sm) for method, handler := range smgBiRpc.Handlers() { @@ -194,6 +196,29 @@ func startSmGeneric(internalRaterChan chan *engine.Responder, server *utils.Serv server.BijsonRegisterOnDisconnect(smg_econns.OnClientDisconnect) } +func startDiameterAgent(internalSMGChan chan rpcclient.RpcClientConnection, exitChan chan bool) { + utils.Logger.Info("Starting CGRateS DiameterAgent service.") + var smgConn *rpcclient.RpcClient + var err error + if cfg.DiameterAgentCfg().SMGeneric == utils.INTERNAL { + smgRpc := <-internalSMGChan + internalSMGChan <- smgRpc + smgConn, err = rpcclient.NewRpcClient("", "", 0, 0, rpcclient.INTERNAL_RPC, smgRpc) + } else { + smgConn, err = rpcclient.NewRpcClient("tcp", cfg.DiameterAgentCfg().SMGeneric, cfg.ConnectAttempts, cfg.Reconnects, utils.GOB, nil) + } + if err != nil { + utils.Logger.Crit(fmt.Sprintf(" Could not connect to SMG: %s", err.Error())) + exitChan <- true + return + } + da := agents.NewDiameterAgent(cfg, smgConn) + if err = da.ListenAndServe(); err != nil { + utils.Logger.Err(fmt.Sprintf(" error: %s!", err)) + } + exitChan <- true +} + func startSmFreeSWITCH(internalRaterChan chan *engine.Responder, cdrDb engine.CdrStorage, exitChan chan bool) { utils.Logger.Info("Starting CGRateS SM-FreeSWITCH service.") var raterConn, cdrsConn engine.Connector @@ -643,7 +668,7 @@ func main() { internalPubSubSChan := make(chan engine.PublisherSubscriber, 1) internalUserSChan := make(chan engine.UserService, 1) internalAliaseSChan := make(chan engine.AliasService, 1) - + internalSMGChan := make(chan rpcclient.RpcClientConnection, 1) // Start balancer service if cfg.BalancerEnabled { go startBalancer(internalBalancerChan, &stopHandled, exitChan) // Not really needed async here but to cope with uniformity @@ -675,7 +700,7 @@ func main() { // Start SM-Generic if cfg.SmGenericConfig.Enabled { - go startSmGeneric(internalRaterChan, server, exitChan) + go startSmGeneric(internalSMGChan, internalRaterChan, server, exitChan) } // Start SM-FreeSWITCH if cfg.SmFsConfig.Enabled { @@ -700,6 +725,10 @@ func main() { server.RpcRegister(smRpc) } + if cfg.DiameterAgentCfg().Enabled { + go startDiameterAgent(internalSMGChan, exitChan) + } + // Start HistoryS service if cfg.HistoryServerEnabled { go startHistoryServer(internalHistorySChan, server, exitChan) diff --git a/config/config.go b/config/config.go index 32c486591..0be3b935d 100644 --- a/config/config.go +++ b/config/config.go @@ -65,7 +65,7 @@ func NewDefaultCGRConfig() (*CGRConfig, error) { cfg.SmFsConfig = new(SmFsConfig) cfg.SmKamConfig = new(SmKamConfig) cfg.SmOsipsConfig = new(SmOsipsConfig) - cfg.DiameterAgentCfg = new(DiameterAgentCfg) + cfg.diameterAgentCfg = new(DiameterAgentCfg) cfg.ConfigReloads = make(map[string]chan struct{}) cfg.ConfigReloads[utils.CDRC] = make(chan struct{}, 1) cfg.ConfigReloads[utils.CDRC] <- struct{}{} // Unlock the channel @@ -232,7 +232,7 @@ type CGRConfig struct { SmFsConfig *SmFsConfig // SM-FreeSWITCH configuration SmKamConfig *SmKamConfig // SM-Kamailio Configuration SmOsipsConfig *SmOsipsConfig // SM-OpenSIPS Configuration - DiameterAgentCfg *DiameterAgentCfg // DiameterAgent configuration + diameterAgentCfg *DiameterAgentCfg // DiameterAgent configuration HistoryServer string // Address where to reach the master history server: HistoryServerEnabled bool // Starts History as server: . HistoryDir string // Location on disk where to store history files. @@ -379,8 +379,8 @@ func (self *CGRConfig) checkConfigSanity() error { } } // DAgent checks - if self.DiameterAgentCfg.Enabled { - if self.DiameterAgentCfg.SMGeneric == utils.INTERNAL && !self.SmGenericConfig.Enabled { + if self.diameterAgentCfg.Enabled { + if self.diameterAgentCfg.SMGeneric == utils.INTERNAL && !self.SmGenericConfig.Enabled { return errors.New("SMGeneric not enabled but referenced by DiameterAgent component") } } @@ -798,7 +798,7 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error { } if jsnDACfg != nil { - if err := self.DiameterAgentCfg.loadFromJsonCfg(jsnDACfg); err != nil { + if err := self.diameterAgentCfg.loadFromJsonCfg(jsnDACfg); err != nil { return err } } @@ -868,7 +868,12 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error { // Use locking to retrieve the configuration, possibility later for runtime reload func (self *CGRConfig) SureTaxCfg() *SureTaxCfg { cfgChan := <-self.ConfigReloads[utils.SURETAX] // Lock config for read or reloads - stCfg := self.sureTaxCfg - self.ConfigReloads[utils.SURETAX] <- cfgChan // unlock config for reloads or read - return stCfg + defer func() { self.ConfigReloads[utils.SURETAX] <- cfgChan }() + return self.sureTaxCfg +} + +func (self *CGRConfig) DiameterAgentCfg() *DiameterAgentCfg { + cfgChan := <-self.ConfigReloads[utils.DIAMETER_AGENT] // Lock config for read or reloads + defer func() { self.ConfigReloads[utils.DIAMETER_AGENT] <- cfgChan }() + return self.diameterAgentCfg } diff --git a/config/config_defaults.go b/config/config_defaults.go index 77709da09..3b6bba33b 100644 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -203,8 +203,8 @@ const CGRATES_CFG_JSON = ` "listen_bijson": "127.0.0.1:2014", // address where to listen for bidirectional JSON-RPC requests "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013> "cdrs": "internal", // address where to reach CDR Server <""|internal|x.y.z.y:1234> - "debit_interval": "10s", // interval to perform debits on. - "min_call_duration": "0s", // only authorize calls with allowed duration higher than this + "debit_interval": "0", // interval to perform debits on. + "min_call_duration": "0", // only authorize calls with allowed duration higher than this "max_call_duration": "3h", // maximum call duration a prepaid call can last }, @@ -262,8 +262,12 @@ const CGRATES_CFG_JSON = ` "diameter_agent": { "enabled": false, // enables the diameter agent: "listen": "127.0.0.1:3868", // address where to listen for diameter requests - "sm_generic": "internal", // Connection towards SMG component for session management + "sm_generic": "internal", // connection towards SMG component for session management "timezone": "", // timezone for timestamps where not specified, empty for general defaults <""|UTC|Local|$IANA_TZ_DB> + "origin_host": "diameter-agent", // diameter Origin-Host AVP used in replies + "origin_realm": "cgrates.org", // diameter Origin-Realm AVP used in replies + "vendor_id": 0, // diameter Vendor-Id AVP used in replies + "product_name": "CGRateS", // diameter Product-Name AVP used in replies "request_processors": [ { "id": "*default", // Identifier of this processor diff --git a/config/config_json_test.go b/config/config_json_test.go index 03c7269d0..51b4b8a5f 100644 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -330,8 +330,8 @@ func TestSmGenericJsonCfg(t *testing.T) { Listen_bijson: utils.StringPointer("127.0.0.1:2014"), Rater: utils.StringPointer("internal"), Cdrs: utils.StringPointer("internal"), - Debit_interval: utils.StringPointer("10s"), - Min_call_duration: utils.StringPointer("0s"), + Debit_interval: utils.StringPointer("0"), + Min_call_duration: utils.StringPointer("0"), Max_call_duration: utils.StringPointer("3h"), } if cfg, err := dfCgrJsonCfg.SmGenericJsonCfg(); err != nil { @@ -416,10 +416,14 @@ func TestSmOsipsJsonCfg(t *testing.T) { func TestDiameterAgentJsonCfg(t *testing.T) { eCfg := &DiameterAgentJsonCfg{ - Enabled: utils.BoolPointer(false), - Listen: utils.StringPointer("127.0.0.1:3868"), - Sm_generic: utils.StringPointer("internal"), - Timezone: utils.StringPointer(""), + Enabled: utils.BoolPointer(false), + Listen: utils.StringPointer("127.0.0.1:3868"), + Sm_generic: utils.StringPointer("internal"), + Timezone: utils.StringPointer(""), + Origin_host: utils.StringPointer("diameter-agent"), + Origin_realm: utils.StringPointer("cgrates.org"), + Vendor_id: utils.IntPointer(0), + Product_name: utils.StringPointer("CGRateS"), Request_processors: &[]*DARequestProcessorJsnCfg{ &DARequestProcessorJsnCfg{ Id: utils.StringPointer("*default"), diff --git a/config/daconfig.go b/config/daconfig.go index 61eb86d8b..5f856c1ab 100644 --- a/config/daconfig.go +++ b/config/daconfig.go @@ -29,6 +29,10 @@ type DiameterAgentCfg struct { Listen string // address where to listen for diameter requests SMGeneric string // connection towards SMG component Timezone string // timezone for timestamps where not specified <""|UTC|Local|$IANA_TZ_DB> + OriginHost string + OriginRealm string + VendorId int + ProductName string RequestProcessors []*DARequestProcessor } @@ -48,6 +52,18 @@ func (self *DiameterAgentCfg) loadFromJsonCfg(jsnCfg *DiameterAgentJsonCfg) erro if jsnCfg.Timezone != nil { self.Timezone = *jsnCfg.Timezone } + if jsnCfg.Origin_host != nil { + self.OriginHost = *jsnCfg.Origin_host + } + if jsnCfg.Origin_realm != nil { + self.OriginRealm = *jsnCfg.Origin_realm + } + if jsnCfg.Vendor_id != nil { + self.VendorId = *jsnCfg.Vendor_id + } + if jsnCfg.Product_name != nil { + self.ProductName = *jsnCfg.Product_name + } if jsnCfg.Request_processors != nil { for _, reqProcJsn := range *jsnCfg.Request_processors { rp := new(DARequestProcessor) diff --git a/config/libconfig_json.go b/config/libconfig_json.go index aa49d499a..88c29de67 100644 --- a/config/libconfig_json.go +++ b/config/libconfig_json.go @@ -241,6 +241,10 @@ type DiameterAgentJsonCfg struct { Listen *string // address where to listen for diameter requests Sm_generic *string // Connection towards generic SM Timezone *string // timezone for timestamps where not specified <""|UTC|Local|$IANA_TZ_DB> + Origin_host *string + Origin_realm *string + Vendor_id *int + Product_name *string Request_processors *[]*DARequestProcessorJsnCfg } diff --git a/data/conf/samples/dmtagent/cgrates.json b/data/conf/samples/dmtagent/cgrates.json new file mode 100644 index 000000000..b60803e90 --- /dev/null +++ b/data/conf/samples/dmtagent/cgrates.json @@ -0,0 +1,82 @@ +{ +// CGRateS Configuration file +// +// Used for cgradmin +// Starts rater, scheduler + +"listen": { + "rpc_json": ":2012", // RPC JSON listening address + "rpc_gob": ":2013", // RPC GOB listening address + "http": ":2080", // HTTP listening address +}, + +"rater": { + "enabled": true, // enable Rater service: + "cdrstats": "internal", // address where to reach the cdrstats service, empty to disable stats functionality<""|internal|x.y.z.y:1234> + "pubsubs": "internal", // address where to reach the pubusb service, empty to disable pubsub functionality: <""|internal|x.y.z.y:1234> + "users": "internal", // address where to reach the user service, empty to disable user profile functionality: <""|internal|x.y.z.y:1234> + "aliases": "internal", +}, + +"scheduler": { + "enabled": true, // start Scheduler service: +}, + +"cdrs": { + "enabled": true, // start the CDR Server service: + "rater": "internal", // address where to reach the Rater for cost calculation, empty to disable functionality: <""|internal|x.y.z.y:1234> + "cdrstats": "internal", // address where to reach the cdrstats service, empty to disable stats functionality<""|internal|x.y.z.y:1234> +}, + +"cdrstats": { + "enabled": true, // starts the cdrstats service: +}, + +"pubsubs": { + "enabled": true, // starts PubSub service: . +}, + +"aliases": { + "enabled": true, // starts Aliases service: . +}, + +"users": { + "enabled": true, // starts User service: . + "indexes": ["Uuid"], // user profile field indexes +}, + +"sm_generic": { + "enabled": true, // starts SessionManager service: + "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013> + "cdrs": "internal", // address where to reach CDR Server <""|internal|x.y.z.y:1234> +}, + +"diameter_agent": { + "enabled": true, // enables the diameter agent: + "listen": "127.0.0.1:3868", // address where to listen for diameter requests + "request_processors": [ + { + "id": "*default", // Identifier of this processor + "dry_run": false, // do not send the CDRs to CDRS, just parse them + "request_filter": "Subscription-Id>Subscription-Type(0)", // filter requests processed by this processor + "continue_on_success": false, // continue to the next template if executed + "content_fields":[ // import content_fields template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value + {"tag": "tor", "cdr_field_id": "TOR", "type": "cdrfield", "value": "^*voice", "mandatory": true}, + {"tag": "accid", "cdr_field_id": "AccId", "type": "cdrfield", "value": "Session-Id", "mandatory": true}, + {"tag": "reqtype", "cdr_field_id": "ReqType", "type": "cdrfield", "value": "^*users", "mandatory": true}, + {"tag": "direction", "cdr_field_id": "Direction", "type": "cdrfield", "value": "^*out", "mandatory": true}, + {"tag": "tenant", "cdr_field_id": "Tenant", "type": "cdrfield", "value": "^*users", "mandatory": true}, + {"tag": "category", "cdr_field_id": "Category", "type": "cdrfield", "value": "^call_;~Calling-Vlr-Number:s/^$/33000/;~Calling-Vlr-Number:s/^(\\d{5})/${1}/", "mandatory": true}, + {"tag": "account", "cdr_field_id": "Account", "type": "cdrfield", "value": "^*users", "mandatory": true}, + {"tag": "subject", "cdr_field_id": "Subject", "type": "cdrfield", "value": "^*users", "mandatory": true}, + {"tag": "destination", "cdr_field_id": "Destination", "type": "cdrfield", "value": "Real-Called-Number", "mandatory": true}, + {"tag": "setup_time", "cdr_field_id": "SetupTime", "type": "cdrfield", "value": "Event-Time", "mandatory": true}, + {"tag": "answer_time", "cdr_field_id": "AnswerTime", "type": "cdrfield", "value": "Event-Time", "mandatory": true}, + {"tag": "usage", "cdr_field_id": "Usage", "type": "cdrfield", "value": "CC-Time", "mandatory": true}, + {"tag": "subscriber_id", "cdr_field_id": "SubscriberId", "type": "cdrfield", "value": "Subscription-Id>Subscription-Id-Data", "mandatory": true}, + ], + }, + ], +}, + +} diff --git a/devel.yaml b/devel.yaml index 1b40bb38a..78b991013 100644 --- a/devel.yaml +++ b/devel.yaml @@ -19,3 +19,4 @@ import: - package: github.com/cgrates/fsock - package: github.com/cenkalti/rpc2 - package: github.com/cenkalti/hub + - package: github.com/fiorix/go-diameter diff --git a/glide.yaml b/glide.yaml index b6a8c8ab1..fb58e9937 100644 --- a/glide.yaml +++ b/glide.yaml @@ -5,7 +5,7 @@ import: - package: github.com/jinzhu/gorm ref: 611e613459953787a01c2afc82835aa0ba01a045 - package: golang.org/x/net - ref: c764672d0ee39ffd83cfcb375804d3181302b62b + ref: 1d9fd3b8333e891c0e7353e1adcfe8a612573033 - package: github.com/DisposaBoy/JsonConfigReader ref: 33a99fdf1d5ee1f79b5077e9c06f955ad356d5f4 - package: github.com/hoisie/redis @@ -25,7 +25,7 @@ import: - package: gopkg.in/fsnotify.v1 ref: 7be54206639f256967dd82fa767397ba5f8f48f5 - package: github.com/peterh/liner - ref: 32e535aff4145c12d1e154754ab144b49ab578e2 + ref: 506a2f061bd0b362a8a2fa445be80386f39dedd8 - package: github.com/cgrates/rpcclient ref: 028c43fc34d32dc9095c7605e2e455e0c7a5ea69 - package: github.com/cgrates/osipsdagram @@ -38,3 +38,5 @@ import: ref: 2d1be381ce47537e9e076b2b76dc70933162e4e9 - package: github.com/cenkalti/hub ref: 57d753b5f4856e77b3cf8ecce78c97215a7d324d + - package: github.com/fiorix/go-diameter + ref: b4c1bac20b8e8e1ac7e17fb54dc83b155aacba21 diff --git a/test.sh b/test.sh index c50c89413..0c62795fc 100755 --- a/test.sh +++ b/test.sh @@ -11,6 +11,7 @@ go test -i github.com/cgrates/cgrates/cdrc go test -i github.com/cgrates/cgrates/utils go test -i github.com/cgrates/cgrates/history go test -i github.com/cgrates/cgrates/cdre +go test -i github.com/cgrates/cgrates/agents go test github.com/cgrates/cgrates/apier/v1 v1=$? @@ -38,5 +39,8 @@ go test github.com/cgrates/cgrates/cache2go c2g=$? go test github.com/cgrates/cgrates/cdre cdre=$? +go test github.com/cgrates/cgrates/agents +ag=$? -exit $v1 && $v2 && $en && $gt && $sm && $cfg && $bl && $cr && $con && $cdrc && $ut && $hs && $c2g && $cdre + +exit $v1 && $v2 && $en && $gt && $sm && $cfg && $bl && $cr && $con && $cdrc && $ut && $hs && $c2g && $cdre && $ag diff --git a/utils/consts.go b/utils/consts.go index d3e491ce1..204589e43 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -30,6 +30,7 @@ var ( const ( VERSION = "0.9.1~rc8" + DIAMETER_FIRMWARE_REVISION = 918 POSTGRES = "postgres" MYSQL = "mysql" MONGO = "mongo"