@ -20,127 +20,10 @@ Track test skips via launchpadlib API and raise alerts if a bug
is fixed but a skip is still in the Tempest test code
"""
import os
import re
from launchpadlib import launchpad
from oslo_log import log as logging
BASEDIR = os . path . abspath ( os . path . join ( os . path . dirname ( __file__ ) , ' .. ' ) )
TESTDIR = os . path . join ( BASEDIR , ' tempest ' )
LPCACHEDIR = os . path . expanduser ( ' ~/.launchpadlib/cache ' )
LOG = logging . getLogger ( __name__ )
def info ( msg , * args , * * kwargs ) :
LOG . info ( msg , * args , * * kwargs )
def debug ( msg , * args , * * kwargs ) :
LOG . debug ( msg , * args , * * kwargs )
def find_skips ( start = TESTDIR ) :
""" Find skipped tests
Returns a list of tuples ( method , bug ) that represent
test methods that have been decorated to skip because of
a particular bug .
"""
results = { }
debug ( " Searching in %s " , start )
for root , _dirs , files in os . walk ( start ) :
for name in files :
if name . startswith ( ' test_ ' ) and name . endswith ( ' py ' ) :
path = os . path . join ( root , name )
debug ( " Searching in %s " , path )
temp_result = find_skips_in_file ( path )
for method_name , bug_no in temp_result :
if results . get ( bug_no ) :
result_dict = results . get ( bug_no )
if result_dict . get ( name ) :
result_dict [ name ] . append ( method_name )
else :
result_dict [ name ] = [ method_name ]
results [ bug_no ] = result_dict
else :
results [ bug_no ] = { name : [ method_name ] }
return results
def find_skips_in_file ( path ) :
""" Return the skip tuples in a test file """
BUG_RE = re . compile ( r ' \ s*@.*skip_because \ (bug=[ \' " ]( \ d+)[ \' " ] ' )
DEF_RE = re . compile ( r ' \ s*def ( \ w+) \ ( ' )
bug_found = False
results = [ ]
with open ( path , ' rb ' ) as content :
lines = content . readlines ( )
for x , line in enumerate ( lines ) :
if not bug_found :
res = BUG_RE . match ( line )
if res :
bug_no = int ( res . group ( 1 ) )
debug ( " Found bug skip %s on line %d " , bug_no , x + 1 )
bug_found = True
else :
res = DEF_RE . match ( line )
if res :
method = res . group ( 1 )
debug ( " Found test method %s skips for bug %d " ,
method , bug_no )
results . append ( ( method , bug_no ) )
bug_found = False
return results
def get_results ( result_dict ) :
results = [ ]
for bug_no in result_dict :
for method in result_dict [ bug_no ] :
results . append ( ( method , bug_no ) )
return results
from tempest . lib . cmd import skip_tracker
if __name__ == ' __main__ ' :
results = find_skips ( )
unique_bugs = sorted ( set ( [ bug for ( method , bug ) in get_results ( results ) ] ) )
unskips = [ ]
duplicates = [ ]
info ( " Total bug skips found: %d " , len ( results ) )
info ( " Total unique bugs causing skips: %d " , len ( unique_bugs ) )
lp = launchpad . Launchpad . login_anonymously ( ' grabbing bugs ' ,
' production ' ,
LPCACHEDIR )
for bug_no in unique_bugs :
bug = lp . bugs [ bug_no ]
duplicate = bug . duplicate_of_link
if duplicate is not None :
dup_id = duplicate . split ( ' / ' ) [ - 1 ]
duplicates . append ( ( bug_no , dup_id ) )
for task in bug . bug_tasks :
info ( " Bug # %7s ( %12s - %12s ) " , bug_no ,
task . importance , task . status )
if task . status in ( ' Fix Released ' , ' Fix Committed ' ) :
unskips . append ( bug_no )
for bug_id , dup_id in duplicates :
if bug_id not in unskips :
dup_bug = lp . bugs [ dup_id ]
for task in dup_bug . bug_tasks :
info ( " Bug # %7s is a duplicate of Bug# %7s ( %12s - %12s ) " ,
bug_id , dup_id , task . importance , task . status )
if task . status in ( ' Fix Released ' , ' Fix Committed ' ) :
unskips . append ( bug_id )
unskips = sorted ( set ( unskips ) )
if unskips :
print ( " The following bugs have been fixed and the corresponding skips " )
print ( " should be removed from the test cases: " )
print ( )
for bug in unskips :
message = " %7s in " % bug
locations = [ " %s " % x for x in results [ bug ] . keys ( ) ]
message + = " and " . join ( locations )
print ( message )
print ( " DEPRECATED: `skip_tracker.py` is already deprecated, "
" use `skip-tracker` command instead. " )
skip_tracker . main ( )