| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // 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; |
| } |