blob: 83ad8b4f2bf321cd6cec8216c766aaf23916ebd7 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2017 Ericsson Telecom AB //
// //
// All rights reserved. This program and the accompanying materials //
// are made available under the terms of the Eclipse Public License v1.0 //
// which accompanies this distribution, and is available at //
// http://www.eclipse.org/legal/epl-v10.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