From 9f84950287ae425314cc05b6f3e341616f652173 Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 15 Jan 2014 15:24:09 +0100 Subject: [PATCH] Localtest for tutfscsv, Monit config for cgrates --- apier/v1/tutfscsv_local_test.go | 194 ++++++++++++++++++++++++++++++++ data/Monit/cgrates.monit | 10 ++ 2 files changed, 204 insertions(+) create mode 100644 apier/v1/tutfscsv_local_test.go create mode 100644 data/Monit/cgrates.monit diff --git a/apier/v1/tutfscsv_local_test.go b/apier/v1/tutfscsv_local_test.go new file mode 100644 index 000000000..6b5f8ef15 --- /dev/null +++ b/apier/v1/tutfscsv_local_test.go @@ -0,0 +1,194 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +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 apier + +import ( + "testing" + "fmt" + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" + "net/rpc" + "net/rpc/jsonrpc" + "os/exec" + "path" + "time" + "reflect" +) + + +// Empty tables before using them +func TestFsCsvCreateTables(t *testing.T) { + if !*testLocal { + return + } + if *storDbType != utils.MYSQL { + t.Fatal("Unsupported storDbType") + } + var mysql *engine.MySQLStorage + if d, err := engine.NewMySQLStorage(cfg.StorDBHost, cfg.StorDBPort, cfg.StorDBName, cfg.StorDBUser, cfg.StorDBPass); err != nil { + t.Fatal("Error on opening database connection: ", err) + } else { + mysql = d.(*engine.MySQLStorage) + } + for _, scriptName := range []string{engine.CREATE_CDRS_TABLES_SQL, engine.CREATE_COSTDETAILS_TABLES_SQL, engine.CREATE_MEDIATOR_TABLES_SQL, engine.CREATE_TARIFFPLAN_TABLES_SQL} { + if err := mysql.CreateTablesFromScript(path.Join(*dataDir, "storage", *storDbType, scriptName)); err != nil { + t.Fatal("Error on mysql creation: ", err.Error()) + return // No point in going further + } + } + for _, tbl := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA} { + if _, err := mysql.Db.Query(fmt.Sprintf("SELECT 1 from %s", tbl)); err != nil { + t.Fatal(err.Error()) + } + } +} + +func TestFsCsvInitDataDb(t *testing.T) { + if !*testLocal { + return + } + ratingDb, err := engine.ConfigureRatingStorage(cfg.RatingDBType, cfg.RatingDBHost, cfg.RatingDBPort, cfg.RatingDBName, cfg.RatingDBUser, cfg.RatingDBPass, cfg.DBDataEncoding) + if err != nil { + t.Fatal("Cannot connect to dataDb", err) + } + accountDb, err := engine.ConfigureAccountingStorage(cfg.AccountDBType, cfg.AccountDBHost, cfg.AccountDBPort, cfg.AccountDBName, + cfg.AccountDBUser, cfg.AccountDBPass, cfg.DBDataEncoding) + if err != nil { + t.Fatal("Cannot connect to dataDb", err) + } + for _, db := range []engine.Storage{ratingDb, accountDb} { + if err := db.Flush(); err != nil { + t.Fatal("Cannot reset dataDb", err) + } + } +} + +// Finds cgr-engine executable and starts it with default configuration +func TestFsCsvStartEngine(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, "-rater", "-scheduler", "-cdrs", "-mediator", "-config", path.Join(*dataDir, "conf", "cgrates.cfg")) + if err := engine.Start(); err != nil { + t.Fatal("Cannot start cgr-engine: ", err.Error()) + } + time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time to rater to fire up +} + +// Connect rpc client to rater +func TestFsCsvRpcConn(t *testing.T) { + if !*testLocal { + return + } + var err error + if cfg.RPCEncoding == utils.JSON { + rater, err = jsonrpc.Dial("tcp", cfg.MediatorRater) + } else { + rater, err = rpc.Dial("tcp", cfg.MediatorRater) + } + if err != nil { + t.Fatal("Could not connect to rater: ", err.Error()) + } +} + + +// Make sure we start with fresh data +func TestFsCsvEmptyCache(t *testing.T) { + if !*testLocal { + return + } + reply := "" + arc := new(utils.ApiReloadCache) + // Simple test that command is executed without errors + if err := rater.Call("ApierV1.ReloadCache", arc, &reply); err != nil { + t.Error("Got error on ApierV1.ReloadCache: ", err.Error()) + } else if reply != "OK" { + t.Error("Calling ApierV1.ReloadCache got reply: ", reply) + } + var rcvStats *utils.CacheStats + expectedStats := &utils.CacheStats{Destinations: 0, RatingPlans: 0, RatingProfiles: 0, Actions: 0} + var args utils.AttrCacheStats + if err := rater.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil { + t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) + } else if !reflect.DeepEqual(expectedStats, rcvStats) { + t.Errorf("Calling ApierV1.GetCacheStats expected: %v, received: %v", expectedStats, rcvStats) + } +} + +func TestFsCsvLoadTariffPlans(t *testing.T) { + if !*testLocal { + return + } + reply := "" + // Simple test that command is executed without errors + attrs := &AttrLoadTPFromFolder{FolderPath: path.Join(*dataDir, "tutorials", "fs_csv", "cgrates", "tariffplans")} + if err := rater.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil { + t.Error("Got error on ApierV1.LoadTariffPlanFromFolder: ", err.Error()) + } else if reply != "OK" { + t.Error("Calling ApierV1.LoadTariffPlanFromFolder got reply: ", reply) + } + var rcvStats *utils.CacheStats + expectedStats := &utils.CacheStats{Destinations: 3, RatingPlans: 1, RatingProfiles: 1, Actions: 2} + var args utils.AttrCacheStats + if err := rater.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil { + t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) + } else if !reflect.DeepEqual(expectedStats, rcvStats) { + t.Errorf("Calling ApierV1.GetCacheStats expected: %v, received: %v", expectedStats, rcvStats) + } +} + +func TestFsCsvCall1(t *testing.T) { + if !*testLocal { + return + } + tStart := time.Date(2014, 01, 15, 6, 0, 0, 0, time.UTC) + tEnd := time.Date(2014, 01, 15, 6, 0, 35, 0, time.UTC) + cd := engine.CallDescriptor { + Direction: "*out", + TOR: "call", + Tenant: "cgrates.org", + Subject: "1001", + Account: "1001", + Destination: "1002", + TimeStart: tStart, + TimeEnd: tEnd, + CallDuration: 35, + } + var cc engine.CallCost + // Simple test that command is executed without errors + if err := rater.Call("Responder.GetCost", cd, &cc); err != nil { + t.Error("Got error on Responder.GetCost: ", err.Error()) + } else if cc.ConnectFee != 0.4 && cc.Cost != 0.2 { + t.Errorf("Calling Responder.GetCost got callcost: %v", cc) + } +} + + +// Simply kill the engine after we are done with tests within this file +func TestFsCsvStopEngine(t *testing.T) { + if !*testLocal { + return + } + exec.Command("pkill", "cgr-engine").Run() +} diff --git a/data/Monit/cgrates.monit b/data/Monit/cgrates.monit new file mode 100644 index 000000000..fe6c56b45 --- /dev/null +++ b/data/Monit/cgrates.monit @@ -0,0 +1,10 @@ +# CGRateS Monit check script + +check process CGRateS with pidfile /var/run/cgrates/cgr-engine.pid + start program = "/etc/init.d/cgrates start" + stop program = "/etc/init.d/cgrates stop" + #if failed host 127.0.0.1 port 2012 type TCP then restart # Rater + #if failed host 127.0.0.1 port 2013 type TCP then restart # History + #if failed host 127.0.0.1 port 2022 type TCP then restart # CDRS + if 5 restarts within 5 cycles then timeout +