diff --git a/apier/cdrstatsv1_local_test.go b/apier/cdrstatsv1_local_test.go index 773003146..304d66336 100644 --- a/apier/cdrstatsv1_local_test.go +++ b/apier/cdrstatsv1_local_test.go @@ -39,7 +39,7 @@ var cdrstRpc *rpc.Client func init() { cdrstCfgPath = path.Join(*dataDir, "conf", "samples", "cdrstatsv1_local_test.cfg") - cdrstCfg, _ = config.NewCGRConfigFromFile(&cfgPath) + cdrstCfg, _ = config.NewCGRConfigFromFile(&cdrstCfgPath) } func TestCDRStatsLclInitDataDb(t *testing.T) { diff --git a/config/config.go b/config/config.go index 9edb3ddaf..f1e6befc3 100644 --- a/config/config.go +++ b/config/config.go @@ -140,6 +140,7 @@ type CGRConfig struct { MailerAuthUser string // Authenticate to email server using this user MailerAuthPass string // Authenticate to email server with this password MailerFromAddr string // From address used when sending emails out + DataFolderPath string // Path towards data folder, for tests internal usage, not loading out of .cfg options } func (self *CGRConfig) setDefaults() error { @@ -241,6 +242,7 @@ func (self *CGRConfig) setDefaults() error { self.MailerAuthUser = "cgrates" self.MailerAuthPass = "CGRateS.org" self.MailerFromAddr = "cgr-mailer@localhost.localdomain" + self.DataFolderPath = "/usr/share/cgrates/" return nil } diff --git a/config/config_test.go b/config/config_test.go index 827a61125..4a0cfca0a 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -144,11 +144,13 @@ func TestDefaults(t *testing.T) { eCfg.MailerAuthUser = "cgrates" eCfg.MailerAuthPass = "CGRateS.org" eCfg.MailerFromAddr = "cgr-mailer@localhost.localdomain" + eCfg.DataFolderPath = "/usr/share/cgrates/" if !reflect.DeepEqual(cfg, eCfg) { t.Log(eCfg) t.Log(cfg) t.Error("Defaults different than expected!") } + } func TestSanityCheck(t *testing.T) { @@ -300,6 +302,7 @@ func TestConfigFromFile(t *testing.T) { eCfg.MailerAuthUser = "test" eCfg.MailerAuthPass = "test" eCfg.MailerFromAddr = "test" + eCfg.DataFolderPath = "/usr/share/cgrates/" if !reflect.DeepEqual(cfg, eCfg) { t.Log(eCfg) t.Log(cfg) diff --git a/data/conf/samples/cdrstatsv1_local_test.cfg b/data/conf/samples/cdrstatsv1_local_test.cfg index 040b13ae3..fd39cacec 100644 --- a/data/conf/samples/cdrstatsv1_local_test.cfg +++ b/data/conf/samples/cdrstatsv1_local_test.cfg @@ -4,14 +4,10 @@ # This file contains the default configuration hardcoded into CGRateS. # This is what you get when you load CGRateS with an empty configuration file. -[global] -rpc_json_listen =:2012 - - [rater] enabled = true -[cdrs] +[cdrs] enabled = true mediator = internal store_disable = true diff --git a/data/conf/samples/tutorial_local_test.cfg b/data/conf/samples/tutorial_local_test.cfg new file mode 100644 index 000000000..96ec8479f --- /dev/null +++ b/data/conf/samples/tutorial_local_test.cfg @@ -0,0 +1,25 @@ +# Real-time Charging System 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. + +[rater] +enabled = true # Enable RaterCDRSExportPath service: . + +[scheduler] +enabled = true # Starts Scheduler service: . + +[cdrs] +enabled = true # Start the CDR Server service: . +mediator = internal # Address where to reach the Mediator. Empty for disabling mediation. <""|internal> + +[cdre] +cdr_format = csv # Exported CDRs format +export_dir = /tmp # Path where the exported CDRs will be placed + +[mediator] +enabled = true # Starts Mediator service: . + +[cdrstats] +enabled = true # Starts the cdrstats service: \ No newline at end of file diff --git a/engine/storage_mysql.go b/engine/storage_mysql.go index 4e3d130c5..fa3dd040c 100644 --- a/engine/storage_mysql.go +++ b/engine/storage_mysql.go @@ -34,8 +34,5 @@ func NewMySQLStorage(host, port, name, user, password string) (Storage, error) { if err != nil { return nil, err } - /*if err := db.Ping(); err != nil { - return nil, err - }*/ return &MySQLStorage{&SQLStorage{db}}, nil } diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 8b5309277..a1cbe994c 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -24,12 +24,14 @@ import ( "encoding/json" "fmt" "io/ioutil" + "path" "strconv" "strings" "time" "github.com/go-sql-driver/mysql" + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" ) @@ -42,7 +44,18 @@ func (self *SQLStorage) Close() { } func (self *SQLStorage) Flush() (err error) { - return + cfg := config.CgrConfig() + for _, scriptName := range []string{CREATE_CDRS_TABLES_SQL, CREATE_TARIFFPLAN_TABLES_SQL} { + if err := self.CreateTablesFromScript(path.Join(cfg.DataFolderPath, "storage", "mysql", scriptName)); err != nil { + return err + } + } + for _, tbl := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA} { + if _, err := self.Db.Query(fmt.Sprintf("SELECT 1 from %s", tbl)); err != nil { + return err + } + } + return nil } func (self *SQLStorage) CreateTablesFromScript(scriptPath string) error { diff --git a/general_tests/tutorial_local_test.go b/general_tests/tutorial_local_test.go new file mode 100644 index 000000000..deec1f466 --- /dev/null +++ b/general_tests/tutorial_local_test.go @@ -0,0 +1,116 @@ +/* +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 general_tests + +import ( + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" + "net/rpc" + "net/rpc/jsonrpc" + "os/exec" + "path" + "testing" + "time" +) + +var tutCfgPath string +var tutCfg *config.CGRConfig +var tutRpc *rpc.Client + +func init() { + tutCfgPath = path.Join(*dataDir, "conf", "samples", "tutorial_local_test.cfg") + tutCfg, _ = config.NewCGRConfigFromFile(&tutCfgPath) + tutCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() + config.SetCgrConfig(tutCfg) +} + +func TestTutLclResetDb(t *testing.T) { + if !*testLocal { + return + } + if db, err := engine.NewMySQLStorage(tutCfg.StorDBHost, tutCfg.StorDBPort, tutCfg.StorDBName, tutCfg.StorDBUser, tutCfg.StorDBPass); err != nil { + t.Error(err) + } else if errFlush := db.Flush(); errFlush != nil { + t.Error(err) + } +} + +func TestTutLclResetDataDb(t *testing.T) { + if !*testLocal { + return + } + ratingDb, err := engine.ConfigureRatingStorage(tutCfg.RatingDBType, tutCfg.RatingDBHost, tutCfg.RatingDBPort, tutCfg.RatingDBName, + tutCfg.RatingDBUser, tutCfg.RatingDBPass, tutCfg.DBDataEncoding) + if err != nil { + t.Fatal(err) + } + accountDb, err := engine.ConfigureAccountingStorage(tutCfg.AccountDBType, tutCfg.AccountDBHost, tutCfg.AccountDBPort, tutCfg.AccountDBName, + tutCfg.AccountDBUser, tutCfg.AccountDBPass, tutCfg.DBDataEncoding) + if err != nil { + t.Fatal(err) + } + for _, db := range []engine.Storage{ratingDb, accountDb} { + if err := db.Flush(); err != nil { + t.Fatal(err) + } + } +} + +func TestTutLclStartEngine(t *testing.T) { + if !*testLocal { + return + } + enginePath, err := exec.LookPath("cgr-engine") + if err != nil { + t.Fatal("Cannot find cgr-engine executable") + } + exec.Command("pkill", "cgr-engine").Run() // Just to make sure another one is not running, bit brutal maybe we can fine tune it + engine := exec.Command(enginePath, "-config", tutCfgPath) + if err := engine.Start(); err != nil { + t.Fatal(err) + } + time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time to rater to fire up +} + +// Connect rpc client to rater +func TestTutLclRpcConn(t *testing.T) { + if !*testLocal { + return + } + var err error + tutRpc, err = jsonrpc.Dial("tcp", tutCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed + if err != nil { + t.Fatal(err) + } +} + +func TestTutLclLoadTariffPlanFromFolder(t *testing.T) { + if !*testLocal { + return + } + reply := "" + attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} + if err := tutRpc.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 +}