From cc67f486ae72680cc946aad9b42c40b3ac827a81 Mon Sep 17 00:00:00 2001 From: arberkatellari Date: Mon, 7 Aug 2023 04:56:50 -0400 Subject: [PATCH] Add more functionality to cgr-tester --- cmd/cgr-tester/cgr-tester.go | 66 ++++++++++++++++++++++-------------- cmd/cgr-tester/sessions.go | 20 +++++++++-- 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/cmd/cgr-tester/cgr-tester.go b/cmd/cgr-tester/cgr-tester.go index c0699e91c..b033f6dd3 100644 --- a/cmd/cgr-tester/cgr-tester.go +++ b/cmd/cgr-tester/cgr-tester.go @@ -49,6 +49,7 @@ var ( exec = cgrTesterFlags.String(utils.ExecCgr, utils.EmptyString, "Pick what you want to test "+ "<*sessions|*cost>") cps = cgrTesterFlags.Int("cps", 100, "run n requests in parallel") + calls = cgrTesterFlags.Int("calls", 100, "run n number of calls") datadbType = cgrTesterFlags.String("datadb_type", cgrConfig.DataDbCfg().Type, "The type of the DataDb database ") datadbHost = cgrTesterFlags.String("datadb_host", cgrConfig.DataDbCfg().Host, "The DataDb host to connect to.") datadbPort = cgrTesterFlags.String("datadb_port", cgrConfig.DataDbCfg().Port, "The DataDb port to bind to.") @@ -82,19 +83,21 @@ var ( requestType = cgrTesterFlags.String("request_type", utils.MetaRated, "Request type of the call") digits = cgrTesterFlags.Int("digits", 10, "Number of digits Account and Destination will have") - tor = cgrTesterFlags.String("tor", utils.MetaVoice, "The type of record to use in queries.") - category = cgrTesterFlags.String("category", "call", "The Record category to test.") - tenant = cgrTesterFlags.String("tenant", "cgrates.org", "The type of record to use in queries.") - subject = cgrTesterFlags.String("subject", "1001", "The rating subject to use in queries.") - destination = cgrTesterFlags.String("destination", "1002", "The destination to use in queries.") - json = cgrTesterFlags.Bool("json", false, "Use JSON RPC") - version = cgrTesterFlags.Bool("version", false, "Prints the application version.") - usage = cgrTesterFlags.String("usage", "1m", "The duration to use in call simulation.") - fPath = cgrTesterFlags.String("file_path", "", "read requests from file with path") - reqSep = cgrTesterFlags.String("req_separator", "\n\n", "separator for requests in file") - verbose = cgrTesterFlags.Bool(utils.VerboseCgr, false, "Enable detailed verbose logging output") - replyCntMux sync.RWMutex - err error + tor = cgrTesterFlags.String("tor", utils.MetaVoice, "The type of record to use in queries.") + category = cgrTesterFlags.String("category", "call", "The Record category to test.") + tenant = cgrTesterFlags.String("tenant", "cgrates.org", "The type of record to use in queries.") + subject = cgrTesterFlags.String("subject", "1001", "The rating subject to use in queries.") + destination = cgrTesterFlags.String("destination", "1002", "The destination to use in queries.") + json = cgrTesterFlags.Bool("json", false, "Use JSON RPC") + version = cgrTesterFlags.Bool("version", false, "Prints the application version.") + usage = cgrTesterFlags.String("usage", "1m", "The duration to use in call simulation.") + fPath = cgrTesterFlags.String("file_path", "", "read requests from file with path") + reqSep = cgrTesterFlags.String("req_separator", "\n\n", "separator for requests in file") + verbose = cgrTesterFlags.Bool(utils.VerboseCgr, false, "Enable detailed verbose logging output") + err error + iterationsPerSecond = 0 + iterationsMux, terminateMx sync.Mutex + countTerminate = 0 ) func durInternalRater(cd *engine.CallDescriptorWithAPIOpts) (time.Duration, error) { @@ -278,27 +281,38 @@ func main() { log.Fatalf("task <%s> is not a supported tester task", *exec) return case utils.MetaSessionS: + if *cps > *calls { + log.Fatalf("Number of *calls <%v> should be bigger or equal to *cps <%v>", *calls, *cps) + return + } digitMin := int64(math.Pow10(*digits - 1)) digitMax := int64(math.Pow10(*digits)) - 1 if *verbose { log.Printf("Digit range: <%v - %v>", digitMin, digitMax) } - var wg sync.WaitGroup + currentCalls := 0 rplyNr := 0 - for i := 0; i < *cps; i++ { - wg.Add(1) - go func() { - defer wg.Done() - if err := callSessions(digitMin, digitMax); err != nil { - log.Fatal(err.Error()) - } - replyCntMux.Lock() - rplyNr++ - replyCntMux.Unlock() - }() + for i := 0; i < *calls+int(maxUsage.Seconds()); i++ { + if currentCalls+*cps > *calls { + *cps = *calls - currentCalls + } + for j := 0; j < *cps; j++ { + go func() { + if err := callSessions(digitMin, digitMax); err != nil { + log.Fatal(err.Error()) + } + rplyNr++ + }() + } + time.Sleep(1 * time.Second) + currentCalls += *cps + log.Printf("Iteration index: <%v>, cps: <%v>, calls finished <%v>", i, iterationsPerSecond, countTerminate) + iterationsPerSecond = 0 + if countTerminate == *calls { + break + } } - wg.Wait() log.Printf("Number of successful calls: %v", rplyNr) case utils.MetaCost: var timeparsed time.Duration diff --git a/cmd/cgr-tester/sessions.go b/cmd/cgr-tester/sessions.go index 35918a502..fecd3ae3f 100644 --- a/cmd/cgr-tester/sessions.go +++ b/cmd/cgr-tester/sessions.go @@ -92,6 +92,9 @@ func callSessions(digitMin, digitMax int64) (err error) { if err = brpc.Call(utils.SessionSv1AuthorizeEvent, authArgs, &authRply); err != nil { return } + iterationsMux.Lock() + iterationsPerSecond++ + iterationsMux.Unlock() if *verbose { log.Printf("Account: <%v>, Destination: <%v>, SessionSv1AuthorizeEvent reply: <%v>", acc, dest, utils.ToJSON(authRply)) } @@ -119,8 +122,16 @@ func callSessions(digitMin, digitMax int64) (err error) { // // SessionSv1UpdateSession // - totalUsage := time.Duration(utils.RandomInteger(int64(*minUsage), int64(*maxUsage))) - for currentUsage := time.Duration(1 * time.Second); currentUsage < totalUsage; currentUsage += *updateInterval { + var totalUsage time.Duration + if *minUsage == *maxUsage { + totalUsage = *maxUsage + } else { + totalUsage = time.Duration(utils.RandomInteger(int64(*minUsage), int64(*maxUsage))) + } + var currentUsage time.Duration + for currentUsage = time.Duration(1 * time.Second); currentUsage < totalUsage; currentUsage += *updateInterval { + + time.Sleep(*updateInterval) event.Event[utils.Usage] = currentUsage.String() upArgs := &sessions.V1UpdateSessionArgs{ @@ -137,7 +148,7 @@ func callSessions(digitMin, digitMax int64) (err error) { } // Delay between last update and termination for a more realistic case - time.Sleep(time.Duration(utils.RandomInteger(10, 20)) * time.Millisecond) + time.Sleep(totalUsage - currentUsage) // // SessionSv1TerminateSession @@ -152,6 +163,9 @@ func callSessions(digitMin, digitMax int64) (err error) { if err = brpc.Call(utils.SessionSv1TerminateSession, tArgs, &tRply); err != nil { return } + terminateMx.Lock() + countTerminate++ + terminateMx.Unlock() if *verbose { log.Printf("Account: <%v>, Destination: <%v>, SessionSv1TerminateSession reply: <%v>", acc, dest, utils.ToJSON(tRply)) }