@ -14,21 +14,21 @@
# under the License.
import argparse
import atexit
import copy
import io
import os
import subprocess
import sys
import tempfile
import warnings
import pbr . version
import six . moves
from stestr import commands
from subunit import run as subunit_run
from testtools import run as testtools_run
from os_testr import regex_builder as rb
from os_testr import testlist_builder as tlb
__version__ = pbr . version . VersionInfo ( ' os_testr ' ) . version_string ( )
@ -107,92 +107,68 @@ def get_parser(args):
def call_testr ( regex , subunit , pretty , list_tests , slowest , parallel , concur ,
until_failure , color , list_of_tests = None , others = None ) :
others = others or [ ]
if parallel :
cmd = [ ' testr ' , ' run ' , ' --parallel ' ]
if concur :
cmd . append ( ' --concurrency= %s ' % concur )
else :
cmd = [ ' testr ' , ' run ' ]
if list_tests :
cmd = [ ' testr ' , ' list-tests ' ]
elif ( subunit or pretty ) and not until_failure :
cmd . append ( ' --subunit ' )
elif not ( subunit or pretty ) and until_failure :
cmd . append ( ' --until-failure ' )
if list_of_tests :
test_fd , test_file_name = tempfile . mkstemp ( )
atexit . register ( os . remove , test_file_name )
test_file = os . fdopen ( test_fd , ' w ' )
test_file . write ( ' \n ' . join ( list_of_tests ) + ' \n ' )
test_file . close ( )
cmd . extend ( ( ' --load-list ' , test_file_name ) )
elif regex :
cmd . append ( regex )
env = copy . deepcopy ( os . environ )
if pretty :
subunit_trace_cmd = [ ' subunit-trace ' , ' --no-failure-debug ' , ' -f ' ]
if color :
subunit_trace_cmd . append ( ' --color ' )
until_failure , color , others = None , blacklist_file = None ,
whitelist_file = None , black_regex = None , load_list = None ) :
# Handle missing .stestr.conf from users from before stestr migration
test_dir = None
top_dir = None
group_regex = None
if not os . path . isfile ( ' .stestr.conf ' ) and os . path . isfile ( ' .testr.conf ' ) :
msg = ( ' No .stestr.conf file found in the CWD. Please create one to '
' to replace the .testr.conf. You can find a script to do this '
' in the stestr git repository. ' )
warnings . warn ( msg )
with open ( ' .testr.conf ' , ' r ' ) as testr_conf_file :
config = six . moves . configparser . ConfigParser ( )
config . readfp ( testr_conf_file )
test_command = config . get ( ' DEFAULT ' , ' test_command ' )
group_regex = None
if config . has_option ( ' DEFAULT ' , ' group_regex ' ) :
group_regex = config . get ( ' DEFAULT ' , ' group_regex ' )
for line in test_command . split ( ' \n ' ) :
if ' subunit.run discover ' in line :
command_parts = line . split ( ' ' )
top_dir_present = ' -t ' in line
for idx , val in enumerate ( command_parts ) :
if top_dir_present :
if val == ' -t ' :
top_dir = command_parts [ idx + 1 ]
test_dir = command_parts [ idx + 2 ]
else :
if val == ' discover ' :
test_dir = command_parts [ idx + 2 ]
elif not os . path . isfile (
' .testr.conf ' ) and not os . path . isfile ( ' .stestr.conf ' ) :
msg = ( ' No .stestr.conf found, please create one. ' )
print ( msg )
sys . exit ( 1 )
# This workaround is necessary because of lp bug 1411804 it's super hacky
# and makes tons of unfounded assumptions, but it works for the most part
if ( subunit or pretty ) and until_failure :
test_list = rb . _get_test_list ( regex , env )
count = 0
failed = False
if not test_list :
print ( " No tests to run " )
return 1
# If pretty or subunit output is desired manually loop forever over
# test individually and generate the desired output in a linear series
# this avoids 1411804 while retaining most of the desired behavior
while True :
for test in test_list :
if pretty :
cmd = [ ' python ' , ' -m ' , ' subunit.run ' , test ]
ps = subprocess . Popen ( cmd , env = env , stdout = subprocess . PIPE )
subunit_trace_cmd . append ( ' --no-summary ' )
proc = subprocess . Popen ( subunit_trace_cmd ,
env = env ,
stdin = ps . stdout )
ps . stdout . close ( )
proc . communicate ( )
if proc . returncode > 0 :
failed = True
break
else :
try :
subunit_run . main ( [ sys . argv [ 0 ] , test ] , sys . stdout )
except SystemExit as e :
if e > 0 :
print ( " Ran %s tests without failure " % count )
return 1
else :
raise
count = count + 1
if failed :
print ( " Ran %s tests without failure " % count )
return 0
# If not until-failure special case call testr like normal
elif pretty and not list_tests :
cmd . extend ( others )
ps = subprocess . Popen ( cmd , env = env , stdout = subprocess . PIPE )
proc = subprocess . Popen ( subunit_trace_cmd ,
env = env , stdin = ps . stdout )
ps . stdout . close ( )
else :
cmd . extend ( others )
proc = subprocess . Popen ( cmd , env = env )
proc . communicate ( )
return_code = proc . returncode
if slowest and not list_tests :
print ( " \n Slowest Tests: \n " )
slow_proc = subprocess . Popen ( [ ' testr ' , ' slowest ' ] , env = env )
slow_proc . communicate ( )
regexes = None
if regex :
regexes = regex . split ( )
serial = not parallel
if list_tests :
# TODO(mtreinish): remove init call after list command detects and
# autocreates the repository
if not os . path . isdir ( ' .stestr ' ) :
commands . init_command ( )
return commands . list_command ( filters = regexes )
return_code = commands . run_command ( filters = regexes , subunit_out = subunit ,
concurrency = concur , test_path = test_dir ,
top_dir = top_dir ,
group_regex = group_regex ,
until_failure = until_failure ,
serial = serial , pretty_out = pretty ,
load_list = load_list ,
blacklist_file = blacklist_file ,
whitelist_file = whitelist_file ,
black_regex = black_regex )
if slowest :
sys . stdout . write ( " \n Slowest Tests: \n " )
commands . slowest_command ( )
return return_code
@ -224,19 +200,16 @@ def call_subunit_run(test_id, pretty, subunit):
testtools_run . main ( [ sys . argv [ 0 ] , test_id ] , sys . stdout )
def _ensure_testr ( ) :
if not os . path . isdir ( ' .testrepository ' ) :
subprocess . call ( [ ' testr ' , ' init ' ] )
def _select_and_call_runner ( opts , exclude_regex , others ) :
ec = 1
_ensure_testr ( )
if not opts . no_discover and not opts . pdb :
ec = call_testr ( exclude_regex , opts . subunit , opts . pretty , opts . list ,
opts . slowest , opts . parallel , opts . concurrency ,
opts . until_failure , opts . color , None , others )
opts . until_failure , opts . color , others ,
blacklist_file = opts . blacklist_file ,
whitelist_file = opts . whitelist_file ,
black_regex = opts . black_regex )
else :
if others :
print ( ' Unexpected arguments: ' + ' ' . join ( others ) )
@ -248,24 +221,6 @@ def _select_and_call_runner(opts, exclude_regex, others):
return ec
def _call_testr_with_list ( opts , test_list , others ) :
ec = 1
_ensure_testr ( )
if opts . list :
print ( " \n " . join ( test_list ) )
return 0
if not test_list :
print ( " No testcase selected to run " )
return 8
ec = call_testr ( None , opts . subunit , opts . pretty , opts . list ,
opts . slowest , opts . parallel , opts . concurrency ,
opts . until_failure , opts . color , test_list , others )
return ec
def ostestr ( args ) :
opts , others = get_parser ( args )
if opts . pretty and opts . subunit :
@ -301,15 +256,7 @@ def ostestr(args):
else :
regex = opts . regex
if opts . blacklist_file or opts . whitelist_file or opts . black_regex :
list_of_tests = tlb . construct_list ( opts . blacklist_file ,
opts . whitelist_file ,
regex ,
opts . black_regex ,
opts . print_exclude )
return ( _call_testr_with_list ( opts , list_of_tests , others ) )
else :
return ( _select_and_call_runner ( opts , regex , others ) )
return _select_and_call_runner ( opts , regex , others )
def main ( ) :