| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // Copyright (c) 2000-2018 Ericsson Telecom AB // |
| // // |
| // All rights reserved. This program and the accompanying materials // |
| // are made available under the terms of the Eclipse Public License v2.0 // |
| // which accompanies this distribution, and is available at // |
| // https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| /////////////////////////////////////////////////////////// |
| // Module: EPTF_CLL_TTCN3Profiler |
| // |
| // Purpose: |
| // This module contains the TTCN3 interface to the TTCN3Profiler feature. |
| // |
| // Module depends on: |
| // none |
| // |
| // Module Parameters: |
| // tsp_EPTF_TTCN3Profiler_usedModules - charstring - sets the file mask |
| // used to select modules to generate TTCN3Profiler info. |
| // (i.e. the list of modules to enable profiler detection ended by .cc) |
| // NOTE: If this module parameter is changed in the config file, |
| // the test case <tc_EPTF_TTCN3Profiler_setConfig> should be executed |
| // and the test suite should be recompiled. |
| // The value "" disables profiler detection. Default: "*Definitions *Functions" |
| // tsp_EPTF_TTCN3Profiler_disabled - boolean - disables profiler detection |
| // without the need of recompile. Default: false |
| // tsp_EPTF_TTCN3Profiler_disableStack - boolean - disables stack monitoring |
| // Disabling it increases performance. Default: false |
| // tsp_EPTF_TTCN3Profiler_noAggregate - boolean - disables aggregation: |
| // does not accumulate called function execution time in the caller scope. |
| // (Needs stack to work) Default: false |
| // |
| // Current Owner: |
| // Jozsef Gyurusi (ethjgi) |
| // |
| // Last Review Date: |
| // 2009-xx-xx |
| // |
| // Detailed Comments: |
| // This module contains the TTCN3 interface functions for TTCN3Profiler. |
| // It integrates seemlessly into titan and mctr_gui. |
| // |
| // The profiler information provided by this feature can be used |
| // to find TTCN3 functions and code lines that nees the most time to execute, |
| // determine what fraction of the total code lines or functions were |
| // executed during the tests, or which functions were not used at all. |
| // |
| // Code line: code line in this context is a TTCN3 statement that can be |
| // executed during runtime. Type definitions, module parameters etc. |
| // are not takes as code lines. Code lines are determined from the |
| // titan-generated cc code, where line information is placed. |
| // |
| // The profiler information automatically accumulated during successive |
| // execution of several test cases, or even between different projects, |
| // if they use the same bin directory. The collected data can be reset |
| // by the corresponding test case provided by this feature. |
| // All collected statistics is available via log files for offline use. |
| // |
| // Requirements: |
| // i) The tools gawk and sed has to be installed and accessible via $PATH. |
| // ii) Required shells: sh, bash, tcsh. |
| // iii) The line number info should be enabled in the Makefile: |
| // COMPILER_FLAGS = -L |
| // |
| // Installation: |
| // 1) Add the current directory as the first item in the $PATH: |
| // set PATH=.:${PATH};export PATH |
| // |
| // 2) Start mctr_gui in that shell and open your project |
| // |
| // 3) Add the TTCN3Profiler.grp to the project (mctr_gui) |
| // |
| // 4) Create symlinks and Makefile, build and run the test cases as usual |
| // |
| // 5) Well done! The profiler information will be printed automatically |
| // to the mctr_gui's main screen when the test suite terminates. |
| // For further customization use the module parameters |
| // and the test cases provided. |
| // |
| // Public functions: |
| // <f_EPTF_TTCN3Profiler_system> |
| // |
| // Public test cases: |
| // <tc_EPTF_TTCN3Profiler_setConfig> |
| // <tc_EPTF_TTCN3Profiler_detailed> |
| // <tc_EPTF_TTCN3Profiler_reset> |
| // <tc_EPTF_TTCN3Profiler_unusedFns> |
| // |
| // All other functions in this module are private! |
| // |
| /////////////////////////////////////////////////////////////// |
| |
| |
| module EPTF_CLL_TTCN3Profiler { |
| |
| modulepar charstring tsp_EPTF_TTCN3Profiler_usedModules := "*Definitions *Functions" // for best results this default value should be the same as TTCN3COV_USEDMODULES_DEFAULT in TTCN3COV compiler |
| modulepar boolean tsp_EPTF_TTCN3Profiler_disabled := false; // disables profiler detection without the need of recompile |
| modulepar boolean tsp_EPTF_TTCN3Profiler_disableStack := false; // disables stack monitoring. Disabling it increases performance. |
| modulepar boolean tsp_EPTF_TTCN3Profiler_noAggregate := false; // disables aggregation: does not accumulate called function execution time in the caller scope. (Needs stack to work) |
| |
| type record of float TTCN3Profiler_FloatList; |
| |
| type record EPTF_TTCN3Profiler_Info { |
| charstring filename, |
| TTCN3Profiler_FloatList times // execution time of lines of code |
| } |
| |
| type record of EPTF_TTCN3Profiler_Info EPTF_TTCN3ProfilerDb; |
| |
| //function f_EPTF_TTCN3Profiler_init(out EPTF_TTCN3ProfilerDb pl_profilerDb) { |
| // pl_profilerDb := {}; |
| //} |
| |
| type record EPTF_TTCN3Profiler_CallStackTimer { |
| integer stackLen, |
| charstring filename, |
| integer lineno, |
| float elapsed |
| } |
| |
| type record of EPTF_TTCN3Profiler_CallStackTimer EPTF_TTCN3Profiler_CallStackTimerDb; |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_TTCN3Profiler_system |
| // |
| // Purpose: |
| // Execute shell command from TTCN |
| // |
| // Parameters: |
| // - pl_command - *in charstring* - the name and arguments of the command to execute |
| // |
| // Return Value: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| external function f_EPTF_TTCN3Profiler_system(in charstring pl_command); |
| |
| type component TTCN3Profiler_CT { |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // TestCase: tc_EPTF_TTCN3Profiler_setConfig |
| // |
| // Purpose: |
| // To set the module parameters defined in the configFile |
| // |
| // Parameters: |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // This test case should be executed after the module parameter |
| // <tsp_EPTF_TTCN3Profiler_usedModules> was changed in the |
| // titan config file. Then the test suite should be rebuilt |
| // so that the new settings could take effect. |
| // |
| /////////////////////////////////////////////////////////// |
| testcase tc_EPTF_TTCN3Profiler_setConfig() runs on TTCN3Profiler_CT { |
| //f_EPTF_TTCN3Profiler_system("./ttcn3cov_gen"); |
| //f_EPTF_TTCN3Profiler_system("./ttcn3cov *.cov | tee TTCN3Profiler.log | grep \"overage\""); |
| var charstring vl_command :="echo 'TTCN3COV_USEDMODULES=\""&tsp_EPTF_TTCN3Profiler_usedModules&"\"' > cov2ttcn3.cfg;"& |
| "rm compile;"& |
| "echo 'Used modules updated to: \""&tsp_EPTF_TTCN3Profiler_usedModules&"\"';"& |
| "echo \\`Rebuild_required_for_the_new_settings_to_take_effect\"'\"!"; |
| f_EPTF_TTCN3Profiler_system(vl_command); |
| setverdict(pass); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // TestCase: tc_EPTF_TTCN3Profiler_reset |
| // |
| // Purpose: |
| // Resets Profiler info |
| // |
| // Parameters: |
| // |
| // Return Value: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| testcase tc_EPTF_TTCN3Profiler_reset() runs on TTCN3Profiler_CT { |
| //f_EPTF_TTCN3Profiler_system("./ttcn3cov_cleanAll"); |
| //f_EPTF_TTCN3Profiler_system("rm *.cov TTCN3Profiler.log"); |
| var charstring vl_command := "bash -c 'rm *.prof TTCN3Profiler.log TTCN3Profiler_unused.log >/dev/null 2>/dev/null'; echo \"TTCN3 profiler info is cleared\""; |
| f_EPTF_TTCN3Profiler_system(vl_command); |
| setverdict(pass); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // TestCase: tc_EPTF_TTCN3Profiler_detailed |
| // |
| // Purpose: |
| // Generate more detailed profiler report |
| // |
| // Parameters: |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // This test case is optimized for mctr_gui |
| // |
| /////////////////////////////////////////////////////////// |
| testcase tc_EPTF_TTCN3Profiler_detailed() runs on TTCN3Profiler_CT { |
| var charstring vl_command := "if [ ! -r TTCN3Profiler.log ]\nthen\necho \"Detailed profiler info is not available.\"\nexit\nfi\ncat TTCN3Profiler.log | grep \"overage\\| call\""; |
| f_EPTF_TTCN3Profiler_system(vl_command); |
| setverdict(pass); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // TestCase: tc_EPTF_TTCN3Profiler_unusedFns |
| // |
| // Purpose: |
| // Prints the list of unused functions in the used modules |
| // |
| // Parameters: |
| // |
| // Return Value: |
| // - |
| // |
| // Detailed Comments: |
| // This test case is optimized for mctr_gui |
| // Note, that the generated list can be very long! |
| // |
| /////////////////////////////////////////////////////////// |
| testcase tc_EPTF_TTCN3Profiler_unusedFns() runs on TTCN3Profiler_CT { |
| var charstring vl_command := "if [ ! -r TTCN3Profiler_unused.log ]\nthen\necho \"Detailed unused functions info is not available.\"\nexit\nfi\ncat TTCN3Profiler_unused.log"; |
| f_EPTF_TTCN3Profiler_system(vl_command); |
| setverdict(pass); |
| } |
| |
| external function f_EPTF_TTCN3Profiler_printStat(in EPTF_TTCN3ProfilerDb pl_profilerDb, in integer pl_codeLines) return charstring; |
| |
| // Prints the statistics for a given module to a string |
| // If this function is changed, the code generated by titan should be copy-pasted to ttcn3prof.cc. |
| //The string constants should be replaced by #define-s! |
| /*function f_EPTF_TTCN3Profiler_printStat(in EPTF_TTCN3ProfilerDb pl_profilerDb, in integer pl_codeLines) return charstring { |
| var charstring vl_profilerStat := ""; |
| var float vl_usage; |
| var integer vl_totalCodeLines := 0; |
| var float vl_totalUsedTimes := 0.0; |
| for(var integer i:=0; i<sizeof(pl_profilerDb);i:=i+1) { |
| if (sizeof(pl_profilerDb[i].times)==0) { |
| continue; |
| } |
| var float vl_usedtimes := 0.0; |
| var charstring vl_filename := pl_profilerDb[i].filename; |
| for(var integer l:=0; l<sizeof(pl_profilerDb[i].times);l:=l+1) { |
| var float vl_time := pl_profilerDb[i].times[l]; |
| if (vl_time==0.0) { |
| continue; // do not generate output for not executed lines |
| } |
| vl_profilerStat := vl_profilerStat |
| & float2str(vl_time) & ":\t"&vl_filename&":"&int2str(l) & "\n"; |
| |
| if (vl_time>0.0) { |
| vl_usedtimes := vl_usedtimes + vl_time; |
| } |
| } |
| var integer vl_codeLines := pl_codeLines; |
| if (vl_codeLines<1) { |
| vl_codeLines := sizeof(pl_profilerDb[i].times); |
| } |
| vl_usage := vl_usedtimes/int2float(vl_codeLines); |
| vl_profilerStat := vl_profilerStat &"\nCode lines in file "&vl_filename&": "&int2str(vl_codeLines); |
| vl_profilerStat := vl_profilerStat &"\nExecution time in file "&vl_filename&": "&float2str(vl_usedtimes); |
| vl_profilerStat := vl_profilerStat &"\nAvgTimePerLine in file "&vl_filename&": "&float2str(vl_usage)&"\n"; |
| |
| vl_totalUsedTimes := vl_totalUsedTimes + vl_usedtimes; |
| vl_totalCodeLines := vl_totalCodeLines + vl_codeLines; |
| } |
| |
| if (vl_totalCodeLines==0) { |
| vl_usage := 0.0; |
| } else { |
| vl_usage := vl_totalUsedTimes/int2float(vl_totalCodeLines); |
| } |
| |
| vl_profilerStat := vl_profilerStat &"\nTotal code lines : "&int2str(vl_totalCodeLines); |
| vl_profilerStat := vl_profilerStat &"\nTotal execution time : "&float2str(vl_totalUsedTimes); |
| vl_profilerStat := vl_profilerStat &"\nOverall time per line: "&float2str(vl_usage)&"\n"; |
| |
| return vl_profilerStat; |
| };*/ |
| |
| |
| } // end of module |