From ff8996241dacc5d1555cc7b18b82c5c68397f16e Mon Sep 17 00:00:00 2001 From: porosnicuadrian Date: Thu, 1 Jul 2021 17:02:57 +0300 Subject: [PATCH] Tested MemoryProfiling for special cases --- apier/v1/core.go | 6 +- apier/v1/core_it_test.go | 182 ++++++++++++++++++++++++++++----------- apier/v1/dispatcher.go | 16 ++++ 3 files changed, 152 insertions(+), 52 deletions(-) diff --git a/apier/v1/core.go b/apier/v1/core.go index 5f9f2f722..635aca2d7 100644 --- a/apier/v1/core.go +++ b/apier/v1/core.go @@ -59,8 +59,8 @@ func (cS *CoreSv1) Sleep(arg *utils.DurationArgs, reply *string) error { } // StartCPUProfiling is used to start CPUProfiling in the given path -func (cS *CoreSv1) StartCPUProfiling(dirPath string, reply *string) error { - if err := cS.cS.StartCPUProfiling(path.Join(dirPath, utils.CpuPathCgr)); err != nil { +func (cS *CoreSv1) StartCPUProfiling(dirPath *utils.DirectoryArgs, reply *string) error { + if err := cS.cS.StartCPUProfiling(path.Join(dirPath.DirPath, utils.CpuPathCgr)); err != nil { return err } *reply = utils.OK @@ -69,7 +69,7 @@ func (cS *CoreSv1) StartCPUProfiling(dirPath string, reply *string) error { // StopCPUProfiling is used to stop CPUProfiling. The file should be written on the path // where the CPUProfiling already started -func (cS *CoreSv1) StopCPUProfiling(_ string, reply *string) error { +func (cS *CoreSv1) StopCPUProfiling(_ *utils.DirectoryArgs, reply *string) error { if err := cS.cS.StopCPUProfiling(); err != nil { return err } diff --git a/apier/v1/core_it_test.go b/apier/v1/core_it_test.go index 3f6f04184..1be6b3c88 100644 --- a/apier/v1/core_it_test.go +++ b/apier/v1/core_it_test.go @@ -47,24 +47,35 @@ var ( testCoreSv1LoadCofig, testCoreSv1InitDataDB, testCoreSv1InitStorDB, - /* - testCoreSv1StartEngineByExecWithCPUProfiling, - testCoreSv1RPCConn, - testCoreSv1StartCPUProfilingErrorAlreadyStarted, - testCoreSv1Sleep, - testCoreSv1StopCPUProfiling, - testCoreSv1KillEngine, - */ + //engine separate with cpu + testCoreSv1StartEngineByExecWithCPUProfiling, + testCoreSv1RPCConn, + testCoreSv1StartCPUProfilingErrorAlreadyStarted, + testCoreSv1Sleep, + testCoreSv1StopCPUProfiling, + testCoreSv1KillEngine, + + //engine separate with memory + testCoreSv1StartEngineByExecWIthMemProfiling, + testCoreSv1RPCConn, + testCoreSv1StartMemProfilingErrorAlreadyStarted, + testCoreSv1Sleep, + testCoreSv1StopMemoryProfiling, + testCoreSv1KillEngine, + testCoreSv1CheckFinalMemProfiling, + // test CPU and Memory just by APIs testCoreSv1StartEngine, testCoreSv1RPCConn, - /* - testCoreSv1StopCPUProfilingBeforeStart, - testCoreSv1StartCPUProfiling, - testCoreSv1Sleep, - testCoreSv1StopCPUProfiling, - */ + //CPUProfiles apis + testCoreSv1StopCPUProfilingBeforeStart, + testCoreSv1StartCPUProfiling, + testCoreSv1Sleep, + testCoreSv1StopCPUProfiling, + + //MemoryProfiles apis + testCoreSv1StopMemProfilingBeforeStart, testCoreSv1StartMemoryProfiling, testCoreSv1Sleep, testCoreSv1StopMemoryProfiling, @@ -110,7 +121,7 @@ func testCoreSv1InitStorDB(t *testing.T) { } func testCoreSv1StartEngineByExecWithCPUProfiling(t *testing.T) { - engine := exec.Command("cgr-engine", "-config_path", coreV1CfgPath, "-cpuprof_dir", "/tmp") + engine := exec.Command("cgr-engine", "-config_path", coreV1CfgPath, "-cpuprof_dir", argPath) if err := engine.Start(); err != nil { t.Error(err) } @@ -139,9 +150,12 @@ func testCoreSv1RPCConn(t *testing.T) { func testCoreSv1StartCPUProfilingErrorAlreadyStarted(t *testing.T) { var reply string + dirPath := &utils.DirectoryArgs{ + DirPath: argPath, + } expectedErr := "CPU profiling already started" if err := coreV1Rpc.Call(utils.CoreSv1StartCPUProfiling, - argPath, &reply); err == nil || err.Error() != expectedErr { + dirPath, &reply); err == nil || err.Error() != expectedErr { t.Errorf("Expected %+v, received %+v", expectedErr, err) } } @@ -152,19 +166,119 @@ func testCoreSv1StartEngine(t *testing.T) { } } +func testCoreSv1StopMemProfilingBeforeStart(t *testing.T) { + var reply string + expectedErr := " Memory Profiling is not started" + if err := coreV1Rpc.Call(utils.CoreSv1StopMemoryProfiling, + new(utils.MemoryPrf), &reply); err == nil || err.Error() != expectedErr { + t.Errorf("Expected %+q, received %+q", expectedErr, err) + } +} + +func testCoreSv1StartEngineByExecWIthMemProfiling(t *testing.T) { + engine := exec.Command("cgr-engine", "-config_path", coreV1CfgPath, + "-memprof_dir", argPath, "-memprof_interval", "100ms", "-memprof_nrfiles", "2") + if err := engine.Start(); err != nil { + t.Error(err) + } + fib := utils.Fib() + var connected bool + for i := 0; i < 200; i++ { + time.Sleep(time.Duration(fib()) * time.Millisecond) + if _, err := jsonrpc.Dial(utils.TCP, coreV1Cfg.ListenCfg().RPCJSONListen); err != nil { + t.Log(err) + } else { + connected = true + break + } + } + if !connected { + t.Errorf("engine did not open port <%s>", coreV1Cfg.ListenCfg().RPCJSONListen) + } +} + +func testCoreSv1StopMemoryProfiling(t *testing.T) { + var reply string + if err := coreV1Rpc.Call(utils.CoreSv1StopMemoryProfiling, + new(utils.MemoryPrf), &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("Unexpected reply returned") + } + + //mem_prof1, mem_prof2 + for i := 1; i <= 2; i++ { + file, err := os.Open(path.Join(argPath, fmt.Sprintf("mem%v.prof", i))) + if err != nil { + t.Error(err) + } + defer file.Close() + + //compare the size + size, err := file.Stat() + if err != nil { + t.Error(err) + } else if size.Size() < int64(415) { + t.Errorf("Size of MemoryProfile %v is lower that expected", size.Size()) + } + //after we checked that CPUProfile was made successfully, can delete it + if err := os.Remove(path.Join(argPath, fmt.Sprintf("mem%v.prof", i))); err != nil { + t.Error(err) + } + } +} + +func testCoreSv1CheckFinalMemProfiling(t *testing.T) { + // as the engine was killed, mem_final.prof was created and we must check it + file, err := os.Open(path.Join(argPath, fmt.Sprintf(utils.MemProfFileCgr))) + if err != nil { + t.Error(err) + } + defer file.Close() + + //compare the size + size, err := file.Stat() + if err != nil { + t.Error(err) + } else if size.Size() < int64(415) { + t.Errorf("Size of MemoryProfile %v is lower that expected", size.Size()) + } + //after we checked that CPUProfile was made successfully, can delete it + if err := os.Remove(path.Join(argPath, fmt.Sprintf(utils.MemProfFileCgr))); err != nil { + t.Error(err) + } +} + +func testCoreSv1StartMemProfilingErrorAlreadyStarted(t *testing.T) { + var reply string + args := &utils.MemoryPrf{ + DirPath: argPath, + Interval: 100 * time.Millisecond, + NrFiles: 2, + } + expErr := "Memory Profiling already started" + if err := coreV1Rpc.Call(utils.CoreSv1StartMemoryProfiling, + args, &reply); err == nil || err.Error() != expErr { + t.Errorf("Expected %+v, received %+v", expErr, err) + } +} + func testCoreSv1StopCPUProfilingBeforeStart(t *testing.T) { var reply string expectedErr := " cannot stop because CPUProfiling is not active" if err := coreV1Rpc.Call(utils.CoreSv1StopCPUProfiling, - utils.EmptyString, &reply); err == nil || err.Error() != expectedErr { + new(utils.DirectoryArgs), &reply); err == nil || err.Error() != expectedErr { t.Errorf("Expected %+q, received %+q", expectedErr, err) } } func testCoreSv1StartCPUProfiling(t *testing.T) { var reply string + dirPath := &utils.DirectoryArgs{ + DirPath: argPath, + } if err := coreV1Rpc.Call(utils.CoreSv1StartCPUProfiling, - argPath, &reply); err != nil { + dirPath, &reply); err != nil { t.Error(err) } else if reply != utils.OK { t.Errorf("Unexpected reply returned") @@ -187,7 +301,7 @@ func testCoreSv1Sleep(t *testing.T) { func testCoreSv1StopCPUProfiling(t *testing.T) { var reply string if err := coreV1Rpc.Call(utils.CoreSv1StopCPUProfiling, - utils.EmptyString, &reply); err != nil { + new(utils.DirectoryArgs), &reply); err != nil { t.Error(err) } else if reply != utils.OK { t.Errorf("Unexpected reply returned") @@ -226,36 +340,6 @@ func testCoreSv1StartMemoryProfiling(t *testing.T) { } } -func testCoreSv1StopMemoryProfiling(t *testing.T) { - var reply string - if err := coreV1Rpc.Call(utils.CoreSv1StopMemoryProfiling, - new(utils.MemoryPrf), &reply); err != nil { - t.Error(err) - } else if reply != utils.OK { - t.Errorf("Unexpected reply returned") - } - - for i := 1; i <= 2; i++ { - file, err := os.Open(path.Join(argPath, fmt.Sprintf("mem%v.prof", i))) - if err != nil { - t.Error(err) - } - defer file.Close() - - //compare the size - size, err := file.Stat() - if err != nil { - t.Error(err) - } else if size.Size() < int64(415) { - t.Errorf("Size of MemoryProfile %v is lower that expected", size.Size()) - } - //after we checked that CPUProfile was made successfully, can delete it - if err := os.Remove(path.Join(argPath, fmt.Sprintf("mem%v.prof", i))); err != nil { - t.Error(err) - } - } -} - func testCoreSv1KillEngine(t *testing.T) { if err := engine.KillEngine(*waitRater); err != nil { t.Error(err) diff --git a/apier/v1/dispatcher.go b/apier/v1/dispatcher.go index 35f7d7aa5..e5b5f9bd9 100644 --- a/apier/v1/dispatcher.go +++ b/apier/v1/dispatcher.go @@ -880,6 +880,22 @@ func (dS *DispatcherCoreSv1) Sleep(arg *utils.DurationArgs, reply *string) error return dS.dS.CoreSv1Sleep(arg, reply) } +func (dS *DispatcherCoreSv1) StartCPUProfiling(args *utils.DirectoryArgs, reply *string) error { + return dS.dS.CoreSv1StartCPUProfiling(args, reply) +} + +func (dS *DispatcherCoreSv1) StopCPUProfiling(args *utils.DirectoryArgs, reply *string) error { + return dS.dS.CoreSv1StopCPUProfiling(args, reply) +} + +func (dS *DispatcherCoreSv1) StartMemoryProfiling(args *utils.MemoryPrf, reply *string) error { + return dS.dS.CoreSv1StartMemoryProfiling(args, reply) +} + +func (dS *DispatcherCoreSv1) StopMemoryProfiling(args *utils.MemoryPrf, reply *string) error { + return dS.dS.CoreSv1StopMemoryProfiling(args, reply) +} + func NewDispatcherRALsV1(dps *dispatchers.DispatcherService) *DispatcherRALsV1 { return &DispatcherRALsV1{dS: dps} }