Add "# @no-test" tag to blacklist statements from test coverage analysis.

It can apply to either single statements:

    print "don't cover"; # @no-test

or a block of statements:

    if ( F )
        { # @no-test
        ...
        }
This commit is contained in:
Jon Siwek 2012-01-13 14:52:58 -06:00
parent b6c3567ba4
commit 713e3ac5d0
6 changed files with 99 additions and 42 deletions

View file

@ -5,7 +5,7 @@
#include "util.h" #include "util.h"
Brofiler::Brofiler() Brofiler::Brofiler()
: delim('\t') : delim('\t'), ignoring(0)
{ {
} }

View file

@ -34,14 +34,24 @@ public:
void SetDelim(char d) { delim = d; } void SetDelim(char d) { delim = d; }
void IncIgnoreDepth() { ignoring++; }
void DecIgnoreDepth() { ignoring--; }
void AddStmt(const Stmt* s) { if ( ignoring == 0 ) stmts.push_back(s); }
private:
/** /**
* The current, global Brofiler instance creates this list at parse-time. * The current, global Brofiler instance creates this list at parse-time.
*/ */
list<const Stmt*> stmts; list<const Stmt*> stmts;
private:
/** /**
* * Indicates whether new statments will not be considered as part of
* coverage statistics because it was marked with the @no-test tag.
*/
unsigned int ignoring;
/**
* This maps Stmt location-desc pairs to the total number of times that * This maps Stmt location-desc pairs to the total number of times that
* Stmt has been executed. The map can be initialized from a file at * Stmt has been executed. The map can be initialized from a file at
* startup time and modified at shutdown time before writing back * startup time and modified at shutdown time before writing back

View file

@ -29,6 +29,8 @@
%token TOK_DOC TOK_POST_DOC %token TOK_DOC TOK_POST_DOC
%token TOK_NO_TEST
%left ',' '|' %left ',' '|'
%right '=' TOK_ADD_TO TOK_REMOVE_FROM %right '=' TOK_ADD_TO TOK_REMOVE_FROM
%right '?' ':' TOK_USING %right '?' ':' TOK_USING
@ -42,6 +44,7 @@
%right '!' %right '!'
%left '$' '[' ']' '(' ')' TOK_HAS_FIELD TOK_HAS_ATTR %left '$' '[' ']' '(' ')' TOK_HAS_FIELD TOK_HAS_ATTR
%type <b> opt_no_test opt_no_test_block
%type <str> TOK_ID TOK_PATTERN_TEXT single_pattern TOK_DOC TOK_POST_DOC %type <str> TOK_ID TOK_PATTERN_TEXT single_pattern TOK_DOC TOK_POST_DOC
%type <str_l> opt_doc_list opt_post_doc_list %type <str_l> opt_doc_list opt_post_doc_list
%type <id> local_id global_id def_global_id event_id global_or_event_id resolve_id begin_func %type <id> local_id global_id def_global_id event_id global_or_event_id resolve_id begin_func
@ -196,6 +199,7 @@ static std::list<std::string>* concat_opt_docs (std::list<std::string>* pre,
%} %}
%union { %union {
bool b;
char* str; char* str;
std::list<std::string>* str_l; std::list<std::string>* str_l;
ID* id; ID* id;
@ -1315,121 +1319,117 @@ attr:
; ;
stmt: stmt:
'{' stmt_list '}' '{' opt_no_test_block stmt_list '}'
{ {
set_location(@1, @3); set_location(@1, @4);
$$ = $2; $$ = $3;
if ( $2 ) brofiler.DecIgnoreDepth();
} }
| TOK_PRINT expr_list ';' | TOK_PRINT expr_list ';' opt_no_test
{ {
set_location(@1, @3); set_location(@1, @3);
$$ = new PrintStmt($2); $$ = new PrintStmt($2);
brofiler.stmts.push_back($$); if ( ! $4 ) brofiler.AddStmt($$);
} }
| TOK_EVENT event ';' | TOK_EVENT event ';' opt_no_test
{ {
set_location(@1, @3); set_location(@1, @3);
$$ = new EventStmt($2); $$ = new EventStmt($2);
brofiler.stmts.push_back($$); if ( ! $4 ) brofiler.AddStmt($$);
} }
| TOK_IF '(' expr ')' stmt | TOK_IF '(' expr ')' stmt
{ {
set_location(@1, @4); set_location(@1, @4);
$$ = new IfStmt($3, $5, new NullStmt()); $$ = new IfStmt($3, $5, new NullStmt());
//brofiler.stmts.push_back($$);
} }
| TOK_IF '(' expr ')' stmt TOK_ELSE stmt | TOK_IF '(' expr ')' stmt TOK_ELSE stmt
{ {
set_location(@1, @4); set_location(@1, @4);
$$ = new IfStmt($3, $5, $7); $$ = new IfStmt($3, $5, $7);
//brofiler.stmts.push_back($$);
} }
| TOK_SWITCH expr '{' case_list '}' | TOK_SWITCH expr '{' case_list '}'
{ {
set_location(@1, @2); set_location(@1, @2);
$$ = new SwitchStmt($2, $4); $$ = new SwitchStmt($2, $4);
//brofiler.stmts.push_back($$);
} }
| for_head stmt | for_head stmt
{ {
$1->AsForStmt()->AddBody($2); $1->AsForStmt()->AddBody($2);
//brofiler.stmts.push_back($1);
} }
| TOK_NEXT ';' | TOK_NEXT ';' opt_no_test
{ {
set_location(@1, @2); set_location(@1, @2);
$$ = new NextStmt; $$ = new NextStmt;
brofiler.stmts.push_back($$); if ( ! $3 ) brofiler.AddStmt($$);
} }
| TOK_BREAK ';' | TOK_BREAK ';' opt_no_test
{ {
set_location(@1, @2); set_location(@1, @2);
$$ = new BreakStmt; $$ = new BreakStmt;
brofiler.stmts.push_back($$); if ( ! $3 ) brofiler.AddStmt($$);
} }
| TOK_RETURN ';' | TOK_RETURN ';' opt_no_test
{ {
set_location(@1, @2); set_location(@1, @2);
$$ = new ReturnStmt(0); $$ = new ReturnStmt(0);
brofiler.stmts.push_back($$); if ( ! $3 ) brofiler.AddStmt($$);
} }
| TOK_RETURN expr ';' | TOK_RETURN expr ';' opt_no_test
{ {
set_location(@1, @2); set_location(@1, @2);
$$ = new ReturnStmt($2); $$ = new ReturnStmt($2);
brofiler.stmts.push_back($$); if ( ! $4 ) brofiler.AddStmt($$);
} }
| TOK_ADD expr ';' | TOK_ADD expr ';' opt_no_test
{ {
set_location(@1, @3); set_location(@1, @3);
$$ = new AddStmt($2); $$ = new AddStmt($2);
brofiler.stmts.push_back($$); if ( ! $4 ) brofiler.AddStmt($$);
} }
| TOK_DELETE expr ';' | TOK_DELETE expr ';' opt_no_test
{ {
set_location(@1, @3); set_location(@1, @3);
$$ = new DelStmt($2); $$ = new DelStmt($2);
brofiler.stmts.push_back($$); if ( ! $4 ) brofiler.AddStmt($$);
} }
| TOK_LOCAL local_id opt_type init_class opt_init opt_attr ';' | TOK_LOCAL local_id opt_type init_class opt_init opt_attr ';' opt_no_test
{ {
set_location(@1, @7); set_location(@1, @7);
$$ = add_local($2, $3, $4, $5, $6, VAR_REGULAR); $$ = add_local($2, $3, $4, $5, $6, VAR_REGULAR);
brofiler.stmts.push_back($$); if ( ! $8 ) brofiler.AddStmt($$);
} }
| TOK_CONST local_id opt_type init_class opt_init opt_attr ';' | TOK_CONST local_id opt_type init_class opt_init opt_attr ';' opt_no_test
{ {
set_location(@1, @6); set_location(@1, @6);
$$ = add_local($2, $3, $4, $5, $6, VAR_CONST); $$ = add_local($2, $3, $4, $5, $6, VAR_CONST);
brofiler.stmts.push_back($$); if ( ! $8 ) brofiler.AddStmt($$);
} }
| TOK_WHEN '(' expr ')' stmt | TOK_WHEN '(' expr ')' stmt
{ {
set_location(@3, @5); set_location(@3, @5);
$$ = new WhenStmt($3, $5, 0, 0, false); $$ = new WhenStmt($3, $5, 0, 0, false);
brofiler.stmts.push_back($$);
} }
| TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' stmt_list '}' | TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
{ {
set_location(@3, @8); set_location(@3, @9);
$$ = new WhenStmt($3, $5, $9, $7, false); $$ = new WhenStmt($3, $5, $10, $7, false);
brofiler.stmts.push_back($$); if ( $9 ) brofiler.DecIgnoreDepth();
} }
@ -1437,21 +1437,20 @@ stmt:
{ {
set_location(@4, @6); set_location(@4, @6);
$$ = new WhenStmt($4, $6, 0, 0, true); $$ = new WhenStmt($4, $6, 0, 0, true);
brofiler.stmts.push_back($$);
} }
| TOK_RETURN TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' stmt_list '}' | TOK_RETURN TOK_WHEN '(' expr ')' stmt TOK_TIMEOUT expr '{' opt_no_test_block stmt_list '}'
{ {
set_location(@4, @9); set_location(@4, @10);
$$ = new WhenStmt($4, $6, $10, $8, true); $$ = new WhenStmt($4, $6, $11, $8, true);
brofiler.stmts.push_back($$); if ( $10 ) brofiler.DecIgnoreDepth();
} }
| expr ';' | expr ';' opt_no_test
{ {
set_location(@1, @2); set_location(@1, @2);
$$ = new ExprStmt($1); $$ = new ExprStmt($1);
brofiler.stmts.push_back($$); if ( ! $3 ) brofiler.AddStmt($$);
} }
| ';' | ';'
@ -1649,6 +1648,18 @@ opt_doc_list:
{ $$ = 0; } { $$ = 0; }
; ;
opt_no_test:
TOK_NO_TEST
{ $$ = true; }
|
{ $$ = false; }
opt_no_test_block:
TOK_NO_TEST
{ $$ = true; brofiler.IncIgnoreDepth(); }
|
{ $$ = false; }
%% %%
int yyerror(const char msg[]) int yyerror(const char msg[])

View file

@ -216,6 +216,8 @@ ESCSEQ (\\([^\n]|[0-7]+|x[[:xdigit:]]+))
} }
} }
#{OWS}@no-test.* return TOK_NO_TEST;
#.* /* eat comments */ #.* /* eat comments */
{WS} /* eat whitespace */ {WS} /* eat whitespace */

View file

@ -0,0 +1,5 @@
1 /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/coverage.coverage-blacklist/coverage-blacklist.bro, line 13 print cover me;
1 /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/coverage.coverage-blacklist/coverage-blacklist.bro, line 17 print always executed;
0 /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/coverage.coverage-blacklist/coverage-blacklist.bro, line 26 print also impossible, but included in code coverage analysis;
1 /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/coverage.coverage-blacklist/coverage-blacklist.bro, line 29 print success;
1 /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/coverage.coverage-blacklist/coverage-blacklist.bro, line 5 print first;

View file

@ -0,0 +1,29 @@
# @TEST-EXEC: BROFILER_FILE=coverage bro -b %INPUT
# @TEST-EXEC: grep %INPUT coverage | sort -k2 >output
# @TEST-EXEC: btest-diff output
print "first";
if ( F )
{ # @no-test
print "hello";
print "world";
}
print "cover me";
if ( T )
{
print "always executed";
}
print "don't cover me"; # @no-test
if ( 0 + 0 == 1 ) print "impossible"; # @no-test
if ( 1 == 0 )
{
print "also impossible, but included in code coverage analysis";
}
print "success";