blob: 1cc07ad4d8c3b2a62fae1ea9ab327c285d862000 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2019 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 //
// //
///////////////////////////////////////////////////////////////////////////////
#include "ttcn3cov.hh"
#include <fcntl.h>
#include <unistd.h>
#include <errno.h> //errno
#include <sys/wait.h>
#include <time.h>
TTCN3COV_GLOBAL::~TTCN3COV_GLOBAL() {
try {
// this 'if' throws an exception on HC:
CHARSTRING lockFileName("");
//fprintf(stdout,"#####EXECUTING COV GLOBAL DESTRUCTOR ON COMP %s ######\n", (const char*)int2str(self));
lockFileName=lockFileName+"TTCN3Coverage_Comp"+int2str(self)+".lck";
//system((const char*)(CHARSTRING("")+"if [ -r "+lockFileName+" ]\nthen\nrm "+lockFileName+"\nfi"));//+";touch RM"+int2str(self)));
unlink((const char*)lockFileName); // remove the file
if (MTC_COMPREF==self) {
//fprintf(stdout,"###### TTCN3Coverage Summary on component %d #######\n",(int)self);
return;
}
} catch(...) {
// This is only executed on HC:
CHARSTRING lockFileName("");
lockFileName=lockFileName+"TTCN3Coverage_Comp_HC_"+int2str((int)::getpid())+".lck";
CHARSTRING cmd("");
cmd = "sleep 1;while [ -n \"`find *.lck ! -name \"TTCN3Coverage_Comp_HC_*.lck\" 2> /dev/null`\" ]\ndo sleep 1\ndone;if [ -z \"`find TTCN3Coverage_Comp_HC*.lck 2> /dev/null`\" ]\nthen\ntouch "+lockFileName+"; sleep 1; if [ \""+lockFileName+"\" != \"`find TTCN3Coverage_Comp_HC*.lck | head -1 2> /dev/null`\" ]\nthen\n\\rm "+lockFileName+";fi;fi";
system((const char*)cmd);
time_t rawtime;
time (&rawtime);
fprintf(stdout,"###### TTCN3Coverage Summary ####### %s", ctime (&rawtime));
fflush(stdout);
cmd = "if [ -f \""+lockFileName+"\" ]\nthen\nwhile [ -n \"`find *.lck ! -name \""+lockFileName+"\" 2> /dev/null`\" ]\ndo sleep 1\ndone;./ttcn3cov_gen;\\rm \""+lockFileName+"\";fi";
system((const char*)cmd);//;touch AAA");
//fprintf(stdout,"#####EXECUTING COV GLOBAL DESTRUCTOR ON COMP HC ######\n");
fprintf(stdout,"###################################\n");
fflush(stdout);
}
}
TTCN3COV& ttcn3cov = TTCN3COV::getInstance();
void TTCN3COV::enterFunction(const char* filename,const int& lineno,const char* functionName) {
executeLine(filename,lineno);
}
void TTCN3COV::executeLine(const char* filename,const int& lineno) {
if (!EPTF__CLL__TTCN3Coverage::tsp__EPTF__TTCN3Coverage__disabled.is_bound() || EPTF__CLL__TTCN3Coverage::tsp__EPTF__TTCN3Coverage__disabled==true) {
return;
}
setLocation(filename);
incCov(currentLocationIdx,lineno);
}
void TTCN3COV::setLocation(const char* filename) {
if(currentLocationFile!=NULL) {
if (strcmp(currentLocationFile,filename)==0) {
return; // location not changed
}
delete [] currentLocationFile;
currentLocationFile = NULL;
};
// store new localtionFile:
currentLocationFile = strdup(filename);
currentLocationIdx = findElement(filename);
if (currentLocationIdx==-1) {
// create new element:
currentLocationIdx = newElement(filename);
}
};
int TTCN3COV::findElement(const char* filename) {
for(int i=0; i<coverageDb.size_of(); ++i) {
if (coverageDb[i].filename()==filename) {
return i;
}
}
return -1; // not found
}
int TTCN3COV::newElement(const char* filename) {
int size(coverageDb.size_of());
coverageDb[size].filename() = filename;
coverageDb[size].lines() = NULL_VALUE;
return size;
}
void TTCN3COV::setCodeLines(const char* moduleName, int codeLines) {
setLocation((const char*)(CHARSTRING(moduleName)+".ttcn"));
coverageDb[currentLocationIdx].codeLines() = codeLines;
}
void TTCN3COV::incCov(const int& element, const int& lineno) {
// increment counter at lineno of the current location
if (lineno==-1) {
return;
}
// set 0 for the unknown lines:
if (coverageDb[element].lines().size_of()<=lineno) {
for(int i=coverageDb[element].lines().size_of(); i<=lineno; ++i) {
coverageDb[element].lines()[i] = 0;
}
}
// increase the counter of the line in the current file:
coverageDb[element].lines()[lineno] = coverageDb[element].lines()[lineno] + 1;
//fprintf(stdout,"%s:%d: execution took %f secs\n",(const char*)coverageDb[element].filename(),lineno,elapsed);
}
void TTCN3COV::writeToFile(const char* data) {
CHARSTRING selfIdStr("HC");
try {
// this 'if' throws an exception on HC:
selfIdStr=int2str(self);
} catch(...) {
}
CHARSTRING filename=CHARSTRING("TTCN3Coverage_Comp")+"_"+selfIdStr+".cov";
int fd = open (filename, O_APPEND | O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd<0) {
fprintf(stderr,"Cannot open target file: %s\n",(const char*)filename);
return;
}
int bytes = write (fd, (const void *) data, strlen(data));
if (bytes<0) {
fprintf(stderr,"Cannot write data to target file: %s\n",(const char*)filename);
return;
}
// flush the data:
fsync(fd);
close(fd);
}
void TTCN3COV::printStat() {
if(currentLocationFile==NULL) {
return; // do not generate anything if no info is available
}
CHARSTRING lockFileName("");
CHARSTRING selfIdStr("HC");
try {
// this 'if' throws an exception on HC:
selfIdStr=int2str(self);
lockFileName=lockFileName+"TTCN3Coverage_Comp"+int2str(self)+".lck";
system((const char*)(CHARSTRING("touch ")+lockFileName));
} catch(...) {
}
CHARSTRING coverageStat = ""
"###################################################\n"
"######### Coverage statistics on comp "+selfIdStr+" ########\n"
"###################################################\n"
+ EPTF__CLL__TTCN3Coverage::f__EPTF__TTCN3Coverage__printStat(coverageDb,codeLines)
+"################## EOF Coverage ###############\n";
writeToFile(coverageStat);
//if (lockFileName!="") {
//system((const char*)(CHARSTRING("rm ")+lockFileName));
//system((const char*)(CHARSTRING("touch RM_")+lockFileName+currentLocationFile+"_"));
//}
//fprintf(stdout,"%s\n",(const char*)coverageStat);
//fprintf(stdout,"###### TTCN3Coverage enabled ######\n");
//fprintf(stdout,"#####EXECUTING COV LOCAL DESTRUCTOR FOR MODULE %s on COMP %s ######\n", (const char*)moduleName, (const char*)selfIdStr);
};
void TTCN3COV::log(const char *fmt, ...)
{
TTCN_Logger::begin_event(TTCN_DEBUG);
va_list pvar;
va_start(pvar, fmt);
TTCN_Logger::log_event_va_list(fmt, pvar);
// fprintf(stdout,fmt, pvar);
// fprintf(stdout,"\n");
va_end(pvar);
TTCN_Logger::end_event();
}
void EPTF__CLL__TTCN3Coverage::f__EPTF__TTCN3Coverage__system(const CHARSTRING& pl__command) {
TTCN3COV::log("TTCN3Coverage: Executing command: %s",(const char*)pl__command);
system((const char*)pl__command);
TTCN3COV::log("TTCN3Coverage: Command finished %s",(const char*)pl__command);
}
void EPTF__CLL__TTCN3Coverage::f__EPTF__TTCN3Coverage__shell(const CHARSTRING& pl__command) {
//calls pl__command
int processPid = fork();
if (processPid == -1) {
// Error
TTCN_error("TTCN3Coverage_shell:" "Cannot fork");
return;
}
if (processPid == 0) {
// Child
//close(fileno(stdout));
//close(fileno(stderr));
//dup(open("/dev/console",
// O_WRONLY|O_APPEND,
// 777));
//close(fileno(stdin));
TTCN3COV::log("Executing command: %s",(const char*)pl__command);
execlp(pl__command, pl__command,
NULL);
fprintf(stderr,"TTCN3Coverage_shell:" "Failed to start the %s",(const char*)pl__command);
fflush(stdout);
fflush(stderr);
exit(errno);
} else {
// Parent process
TTCN3COV::log("TTCN3Coverage_shell: %s launched with PID: %i",(const char*)pl__command, processPid);
int processExitCode=0;
int pid = wait(&processExitCode);
if (pid!=processPid) {
TTCN3COV::log("TTCN3Coverage_shell: other child died with pid: %d, exit code: %d", pid, processExitCode);
return;
}
TTCN3COV::log("TTCN3Coverage_shell: Child process exit status is: %d", processExitCode);
fflush(stdout);
fflush(stderr);
}
}
void EPTF__CLL__TTCN3Coverage::f__EPTF__TTCN3Coverage__detailed() {
//calls ttcn3cov *.cov > TTCN3Coverage.log
f__EPTF__TTCN3Coverage__system("if [ ! -r TTCN3Coverage.log ]\nthen\necho \"Detailed coverage info is not available.\"\nexit\nfi\ncat TTCN3Coverage.log | grep \"overage\\| call\"");
}
void EPTF__CLL__TTCN3Coverage::f__EPTF__TTCN3Coverage__reset() {
//calls rm *.cov TTCN3Coverage.log
f__EPTF__TTCN3Coverage__system("rm *.cov TTCN3Coverage.log TTCN3Coverage_unused.log; echo \"TTCN3 coverage info is cleared\"");
}
void EPTF__CLL__TTCN3Coverage::f__EPTF__TTCN3Coverage__unusedFns() {
//calls rm *.cov TTCN3Coverage.log
f__EPTF__TTCN3Coverage__system("if [ ! -r TTCN3Coverage_unused.log ]\nthen\necho \"Detailed unused functions info is not available.\"\nexit\nfi\ncat TTCN3Coverage_unused.log");
}
#define cs_0 ""
#define cs_3 "\n"
#define cs_8 "\nCode coverage in file "
#define cs_6 "\nCode lines in file "
#define cs_7 "\nExecuted lines in file "
#define cs_12 "\nOverall code coverage: "
#define cs_10 "\nTotal code lines : "
#define cs_11 "\nTotal executed lines : "
#define cs_2 ":"
#define cs_1 ":\t"
#define cs_5 ": "
#define cs_4 "Total lines in file "
#define cs_9 "Total source lines : "
CHARSTRING EPTF__CLL__TTCN3Coverage::f__EPTF__TTCN3Coverage__printStat(const EPTF__TTCN3CoverageDb& pl__coverageDb, const INTEGER& pl__codeLines)
{
TTCN_Location current_location("EPTF_CLL_TTCN3Coverage.ttcn", 71, TTCN_Location::LOCATION_FUNCTION, "f_EPTF_TTCN3Coverage_printStat");
current_location.update_lineno(72);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 72 */
CHARSTRING vl__coverageStat(cs_0);
current_location.update_lineno(73);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 73 */
FLOAT vl__usage;
current_location.update_lineno(74);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 74 */
INTEGER vl__totalCodeLines(0);
current_location.update_lineno(75);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 75 */
INTEGER vl__totalUsedLines(0);
current_location.update_lineno(76);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 76 */
INTEGER vl__totalSourceLines(0);
{
INTEGER i(0);
current_location.update_lineno(77);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 77 */
for ( ; ; ) {
current_location.update_lineno(77);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 77 */
if (!(i < pl__coverageDb.size_of())) break;
{
current_location.update_lineno(78);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 78 */
// if ((pl__coverageDb[i].lines().size_of() == 0)) {
// current_location.update_lineno(79);
// /* EPTF_CLL_TTCN3Coverage.ttcn, line 79 */
// goto tmp_1;
// }
current_location.update_lineno(81);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 81 */
INTEGER vl__usedLines(0);
current_location.update_lineno(82);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 82 */
CHARSTRING vl__filename(pl__coverageDb[i].filename());
{
INTEGER l(0);
current_location.update_lineno(83);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 83 */
for ( ; ; ) {
current_location.update_lineno(83);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 83 */
if (!(l < pl__coverageDb[i].lines().size_of())) break;
{
current_location.update_lineno(84);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 84 */
INTEGER vl__cov(pl__coverageDb[i].lines()[l]);
current_location.update_lineno(85);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 85 */
if ((vl__cov == 0)) {
current_location.update_lineno(86);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 86 */
goto tmp_2;
}
current_location.update_lineno(88);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 88 */
vl__coverageStat = ((((((vl__coverageStat + int2str(vl__cov)) + cs_1) + vl__filename) + cs_2) + int2str(l)) + cs_3);
current_location.update_lineno(91);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 91 */
if ((vl__cov > 0)) {
current_location.update_lineno(92);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 92 */
vl__usedLines = (vl__usedLines + 1);
}
}
tmp_2:
current_location.update_lineno(83);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 83 */
l = (l + 1);
}
}
current_location.update_lineno(95);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 95 */
INTEGER vl__codeLines(vl__usedLines);
current_location.update_lineno(321);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 321 */
{
boolean tmp_5;
{
boolean tmp_1 = pl__coverageDb.is_bound();
if(tmp_1) {
const int tmp_2 = i;
tmp_1 = (tmp_2 >= 0) && (pl__coverageDb.size_of() > tmp_2);
if(tmp_1) {
const EPTF__TTCN3Coverage__Info& tmp_3 = pl__coverageDb[tmp_2];
tmp_1 = tmp_3.is_bound();
if(tmp_1) {
const INTEGER& tmp_4 = tmp_3.codeLines();
tmp_1 = tmp_4.is_bound();
}
}
}
tmp_5 = tmp_1;
}
if (tmp_5) {
current_location.update_lineno(322);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 322 */
vl__codeLines = const_cast< const EPTF__TTCN3CoverageDb&>(pl__coverageDb)[i].codeLines();
}
}
current_location.update_lineno(96);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 96 */
if ((vl__codeLines < 1)) {
current_location.update_lineno(321);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 321 */
vl__usage = 0.0;
}
else {
current_location.update_lineno(323);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 323 */
vl__usage = (int2float(vl__usedLines) / int2float(vl__codeLines));
}
current_location.update_lineno(100);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 100 */
vl__coverageStat = ((((vl__coverageStat + cs_4) + vl__filename) + cs_5) + int2str(pl__coverageDb[i].lines().size_of()));
current_location.update_lineno(101);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 101 */
vl__coverageStat = ((((vl__coverageStat + cs_6) + vl__filename) + cs_5) + int2str(vl__codeLines));
current_location.update_lineno(102);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 102 */
vl__coverageStat = ((((vl__coverageStat + cs_7) + vl__filename) + cs_5) + int2str(vl__usedLines));
current_location.update_lineno(103);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 103 */
vl__coverageStat = (((((vl__coverageStat + cs_8) + vl__filename) + cs_5) + float2str(vl__usage)) + cs_3);
current_location.update_lineno(105);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 105 */
vl__totalSourceLines = (vl__totalSourceLines + pl__coverageDb[i].lines().size_of());
current_location.update_lineno(106);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 106 */
vl__totalUsedLines = (vl__totalUsedLines + vl__usedLines);
current_location.update_lineno(107);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 107 */
vl__totalCodeLines = (vl__totalCodeLines + vl__codeLines);
}
tmp_1:
current_location.update_lineno(77);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 77 */
i = (i + 1);
}
}
current_location.update_lineno(110);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 110 */
if ((vl__totalCodeLines == 0)) {
current_location.update_lineno(111);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 111 */
vl__usage = 0.0;
}
else {
current_location.update_lineno(113);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 113 */
vl__usage = (int2float(vl__totalUsedLines) / int2float(vl__totalCodeLines));
}
current_location.update_lineno(116);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 116 */
vl__coverageStat = ((vl__coverageStat + cs_9) + int2str(vl__totalSourceLines));
current_location.update_lineno(117);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 117 */
vl__coverageStat = ((vl__coverageStat + cs_10) + int2str(vl__totalCodeLines));
current_location.update_lineno(118);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 118 */
vl__coverageStat = ((vl__coverageStat + cs_11) + int2str(vl__totalUsedLines));
current_location.update_lineno(119);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 119 */
vl__coverageStat = (((vl__coverageStat + cs_12) + float2str(vl__usage)) + cs_3);
current_location.update_lineno(121);
/* EPTF_CLL_TTCN3Coverage.ttcn, line 121 */
return vl__coverageStat;
}