From 04597495e59eba0bfa5c7935c30ee326fdc2c006 Mon Sep 17 00:00:00 2001 From: Alex White Date: Thu, 25 Feb 2021 10:47:58 -0600 Subject: coverage/reports: Improve formatting and clarity The coverage reports contain places where they display incorrect or vague information particularly when some statistic is unavailable. This has been fixed. The formatting and wording of various things has been improved as well. --- tester/covoar/ObjdumpProcessor.cc | 5 ++ tester/covoar/ReportsBase.cc | 21 ++++- tester/covoar/ReportsHtml.cc | 159 +++++++++++++++++++++----------------- tester/covoar/ReportsText.cc | 76 ++++++++++-------- tester/rt/coverage.py | 19 ++++- 5 files changed, 173 insertions(+), 107 deletions(-) diff --git a/tester/covoar/ObjdumpProcessor.cc b/tester/covoar/ObjdumpProcessor.cc index 16774d9..62a06c5 100644 --- a/tester/covoar/ObjdumpProcessor.cc +++ b/tester/covoar/ObjdumpProcessor.cc @@ -370,6 +370,11 @@ namespace Coverage { break; } + // Remove any extra line break + if (line.back() == '\n') { + line.erase(line.end() - 1); + } + lineInfo.line = line; lineInfo.address = 0xffffffff; lineInfo.isInstruction = false; diff --git a/tester/covoar/ReportsBase.cc b/tester/covoar/ReportsBase.cc index 0be5567..1615c0b 100644 --- a/tester/covoar/ReportsBase.cc +++ b/tester/covoar/ReportsBase.cc @@ -161,6 +161,24 @@ void ReportsBase::CloseSymbolSummaryFile( CloseFile( aFile ); } +std::string expand_tabs(const std::string& in) { + std::string expanded = ""; + int i = 0; + + for (char c : in) { + if (c == '\t') { + int num_tabs = 4 - (i % 4); + expanded.append(num_tabs, ' '); + i += num_tabs; + } else { + expanded += c; + i++; + } + } + + return expanded; +} + /* * Write annotated report */ @@ -237,7 +255,8 @@ void ReportsBase::WriteAnnotatedReport( } } - snprintf( textLine, LINE_LENGTH, "%-70s", itr->line.c_str() ); + std::string textLineWithoutTabs = expand_tabs(itr->line); + snprintf( textLine, LINE_LENGTH, "%-90s", textLineWithoutTabs.c_str() ); line = textLine + annotation; PutAnnotatedLine( aFile, state, line, id); diff --git a/tester/covoar/ReportsHtml.cc b/tester/covoar/ReportsHtml.cc index ebc6ee0..cce0a4f 100644 --- a/tester/covoar/ReportsHtml.cc +++ b/tester/covoar/ReportsHtml.cc @@ -89,7 +89,7 @@ namespace Coverage { PRINT_ITEM( "Branch Report", "branch" ); PRINT_ITEM( "Annotated Assembly", "annotated" ); PRINT_ITEM( "Symbol Summary", "symbolSummary" ); - PRINT_ITEM( "Size Report", "sizes" ); + PRINT_ITEM( "Uncovered Range Size Report", "sizes" ); PRINT_TEXT_ITEM( "Explanations Not Found", "ExplanationsNotFound.txt" ); @@ -176,7 +176,7 @@ namespace Coverage { // Put header information into the file fprintf( aFile, - "Branch Report</title\n" + "<title>Branch Report\n" "
" ); @@ -321,7 +321,7 @@ namespace Coverage { // Put header information into the file fprintf( aFile, - "Size Report\n" + "Uncovered Range Size Report\n" "
" ); @@ -334,7 +334,7 @@ namespace Coverage { fprintf( aFile, - "Size Report
\n" + "Uncovered Range Size Report
\n" "
%s
\n" "\n" "getNumberBranchesFound() != 0) fprintf( report, "All branch paths taken.\n" ); else fprintf( report, "No branch information found.\n" ); @@ -861,90 +861,107 @@ namespace Coverage { symbol->first.c_str() ); - // Total Size in Bytes - fprintf( - report, - "\n", - symbol->second.stats.sizeInBytes - ); - - // Total Size in Instructions - fprintf( - report, - "\n", - symbol->second.stats.sizeInInstructions - ); - - // Total Uncovered Ranges - fprintf( - report, - "\n", - symbol->second.stats.uncoveredRanges - ); - - // Uncovered Size in Bytes - fprintf( - report, - "\n", - symbol->second.stats.uncoveredBytes - ); - - // Uncovered Size in Instructions - fprintf( - report, - "\n", - symbol->second.stats.uncoveredInstructions - ); + if (symbol->second.stats.sizeInBytes == 0) { + // The symbol has never been seen. Write "unknown" for all columns. + fprintf( + report, + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + ); + } else { + // Total Size in Bytes + fprintf( + report, + "\n", + symbol->second.stats.sizeInBytes + ); - // Total number of branches - fprintf( - report, - "\n", - symbol->second.stats.branchesNotExecuted + symbol->second.stats.branchesExecuted - ); + // Total Size in Instructions + fprintf( + report, + "\n", + symbol->second.stats.sizeInInstructions + ); - // Total Always Taken - fprintf( - report, - "\n", - symbol->second.stats.branchesAlwaysTaken - ); + // Total Uncovered Ranges + fprintf( + report, + "\n", + symbol->second.stats.uncoveredRanges + ); - // Total Never Taken - fprintf( - report, - "\n", - symbol->second.stats.branchesNeverTaken - ); + // Uncovered Size in Bytes + fprintf( + report, + "\n", + symbol->second.stats.uncoveredBytes + ); - // % Uncovered Instructions - if ( symbol->second.stats.sizeInInstructions == 0 ) + // Uncovered Size in Instructions fprintf( report, - "\n" + "\n", + symbol->second.stats.uncoveredInstructions ); - else + + // Total number of branches fprintf( report, - "\n", - (symbol->second.stats.uncoveredInstructions*100.0)/ - symbol->second.stats.sizeInInstructions + "\n", + symbol->second.stats.branchesNotExecuted + symbol->second.stats.branchesExecuted ); - // % Uncovered Bytes - if ( symbol->second.stats.sizeInBytes == 0 ) + // Total Always Taken fprintf( report, - "\n" + "\n", + symbol->second.stats.branchesAlwaysTaken ); - else + + // Total Never Taken fprintf( report, - "\n", - (symbol->second.stats.uncoveredBytes*100.0)/ - symbol->second.stats.sizeInBytes + "\n", + symbol->second.stats.branchesNeverTaken ); + // % Uncovered Instructions + if ( symbol->second.stats.sizeInInstructions == 0 ) + fprintf( + report, + "\n" + ); + else + fprintf( + report, + "\n", + (symbol->second.stats.uncoveredInstructions*100.0)/ + symbol->second.stats.sizeInInstructions + ); + + // % Uncovered Bytes + if ( symbol->second.stats.sizeInBytes == 0 ) + fprintf( + report, + "\n" + ); + else + fprintf( + report, + "\n", + (symbol->second.stats.uncoveredBytes*100.0)/ + symbol->second.stats.sizeInBytes + ); + } + fprintf( report, "\n"); return true; } diff --git a/tester/covoar/ReportsText.cc b/tester/covoar/ReportsText.cc index 33d3509..a3923e6 100644 --- a/tester/covoar/ReportsText.cc +++ b/tester/covoar/ReportsText.cc @@ -52,7 +52,7 @@ bool ReportsText::PutNoBranchInfo( FILE* report ) { - if ( BranchInfoAvailable ) + if ( BranchInfoAvailable && SymbolsToAnalyze->getNumberBranchesFound() != 0 ) fprintf( report, "All branch paths taken.\n" ); else fprintf( report, "No branch information found.\n" ); @@ -235,38 +235,52 @@ bool ReportsText::PutSymbolSummaryLine( float uncoveredBytes; float uncoveredInstructions; - if ( symbol->second.stats.sizeInInstructions == 0 ) - uncoveredInstructions = 0; - else - uncoveredInstructions = (symbol->second.stats.uncoveredInstructions*100.0)/ - symbol->second.stats.sizeInInstructions; + if (symbol->second.stats.sizeInBytes == 0) { + fprintf( + report, + "============================================\n" + "Symbol : %s\n" + " *** NEVER REFERENCED ***\n\n" + "This symbol was never referenced by an analyzed executable.\n" + "Therefore there is no size or disassembly for this symbol.\n" + "This could be due to symbol misspelling or lack of a test for\n" + "this symbol.\n", + symbol->first.c_str() + ); + } else { + if ( symbol->second.stats.sizeInInstructions == 0 ) + uncoveredInstructions = 0; + else + uncoveredInstructions = (symbol->second.stats.uncoveredInstructions*100.0)/ + symbol->second.stats.sizeInInstructions; - if ( symbol->second.stats.sizeInBytes == 0 ) - uncoveredBytes = 0; - else - uncoveredBytes = (symbol->second.stats.uncoveredBytes*100.0)/ - symbol->second.stats.sizeInBytes; + if ( symbol->second.stats.sizeInBytes == 0 ) + uncoveredBytes = 0; + else + uncoveredBytes = (symbol->second.stats.uncoveredBytes*100.0)/ + symbol->second.stats.sizeInBytes; - fprintf( - report, - "============================================\n" - "Symbol : %s\n" - "Total Size in Bytes : %d\n" - "Total Size in Instructions : %d\n" - "Total number Branches : %d\n" - "Total Always Taken : %d\n" - "Total Never Taken : %d\n" - "Percentage Uncovered Instructions : %.2f\n" - "Percentage Uncovered Bytes : %.2f\n", - symbol->first.c_str(), - symbol->second.stats.sizeInBytes, - symbol->second.stats.sizeInInstructions, - symbol->second.stats.branchesNotExecuted + symbol->second.stats.branchesExecuted, - symbol->second.stats.branchesAlwaysTaken, - symbol->second.stats.branchesNeverTaken, - uncoveredInstructions, - uncoveredBytes - ); + fprintf( + report, + "============================================\n" + "Symbol : %s\n" + "Total Size in Bytes : %d\n" + "Total Size in Instructions : %d\n" + "Total number Branches : %d\n" + "Total Always Taken : %d\n" + "Total Never Taken : %d\n" + "Percentage Uncovered Instructions : %.2f\n" + "Percentage Uncovered Bytes : %.2f\n", + symbol->first.c_str(), + symbol->second.stats.sizeInBytes, + symbol->second.stats.sizeInInstructions, + symbol->second.stats.branchesNotExecuted + symbol->second.stats.branchesExecuted, + symbol->second.stats.branchesAlwaysTaken, + symbol->second.stats.branchesNeverTaken, + uncoveredInstructions, + uncoveredBytes + ); + } fprintf(report, "============================================\n"); return true; diff --git a/tester/rt/coverage.py b/tester/rt/coverage.py index 8d176c3..d62c853 100644 --- a/tester/rt/coverage.py +++ b/tester/rt/coverage.py @@ -121,7 +121,7 @@ class report_gen_html: def _prepare_head_section(self): head_section = '' + os.linesep - head_section += ' RTEMS coverage report' + os.linesep + head_section += ' RTEMS Coverage Report' + os.linesep head_section += ' ' + os.linesep head_section += '' + os.linesep return head_section def _prepare_index_content(self, partial_reports): - header = "

RTEMS coverage analysis report

" + os.linesep + header = "

RTEMS Coverage Analysis Report

" + os.linesep header += "

Coverage reports by symbols sets:

" + os.linesep - table = "
%d%d%d%d%dunknownunknownunknownunknownunknownunknownunknownunknownunknownunknown%d%d%d%d%d%d%d100.00%d%.2f%d100.00%d%.2f%d100.00%.2f100.00%.2f
" + os.linesep + table = "
" + os.linesep + table += "" + os.linesep table += self._header_row() - for symbol_set in partial_reports: + table += "" + os.linesep + table += "" + os.linesep + for symbol_set in sorted(partial_reports.keys()): table += self._row(symbol_set, partial_reports[symbol_set]) + table += "" + os.linesep table += "

" timestamp = "Analysis performed on " + datetime.datetime.now().ctime() return "\n" + header + table + timestamp + "\n" -- cgit v1.2.3