322 lines
9.3 KiB
Python

#!/usr/bin/env python
import argparse
import os
import sys
import subprocess
import logging
## Designate test applications here
def generate_constants():
"""
Applications are registered here.
Returns a dictionary of test modules
and their test cases.
"""
## Every application test suite will have these
base_tests = dict()
base_tests['Make_Test'] = "a_make_test"
base_tests['Make_Ut_Test'] = "b_make_ut_test"
supported_apps = dict()
## Define apps here
## All supported applications must have the base tests
supported_apps['active_tester'] = base_tests.copy()
# supported_apps['app1'] = base_tests.copy()
supported_apps['app2'] = base_tests.copy()
# supported_apps['cnt_only'] = base_tests.copy()
## Define test cases and their descriptions here
## Define 'test_module' as the module in the application
## Define the test type as the method name within the test module
supported_apps['active_tester']['test_file'] = "active_tester_nose_test.py"
supported_apps['active_tester']['Sync_Input_Test'] = "c_Sync_InputPortF32_test"
supported_apps['active_tester']['Async_Input_Test'] = "d_Async_InputPortU32_test"
# supported_apps['app1']['test_file'] = "app1_nose_test.py"
# supported_apps['app1']['Port_Send_Test'] = "c_port_send_test"
supported_apps['app2']['test_file'] = "app2_nose_test.py"
supported_apps['app2']['Void_Send_Test'] = "c_void_send_test"
supported_apps['app2']['Port_Send_Test'] = "d_port_send_test"
# supported_apps['cnt_only']['test_file'] = "cnt_only_nose_test.py"
# supported_apps['cnt_only']['Port_Send_Test'] = "c_port_send_test"
return supported_apps
def generate_entry(key, supported_apps):
"""
Generates an entry for
the help text.
"""
entry_template = """\n\n{app_name}""".format(app_name=key)
entry_template += """\n----------"""
for test_t in supported_apps[key]:
if test_t == 'test_file':
continue
entry_template += """\n{test_type}""".format(test_type=test_t)
return entry_template
def get_app_list():
"""
Return a formated list
of test modules and their
test cases.
"""
app_list = """--------- Supported Applications ---------"""
supported_apps = generate_constants()
## Add app_name and test methods combination to app_list
for key in supported_apps:
entry = generate_entry(key, supported_apps)
app_list += entry
return app_list
def process_args(args):
"""
Process user arguments.
"""
# Application Dictionary
supported_apps = generate_constants()
nose_call = """nosetests -v"""
## Run all tests if no applications are specified
if len(args.applications) == 0:
for key in supported_apps:
logging.debug("app: %s" % key)
nose_call += " "+key+" "
else:
for appTest in args.applications:
nose_args = parse_app(appTest)
logging.debug("nose_args: %s" % nose_args)
nose_call += nose_args
logging.debug('nose_call: %s' % nose_call)
return nose_call
def generate_for_method(test_method):
"""
@param test_method: What test case to run.
Returns argument string for nose.
"""
supported_apps = generate_constants()
cmd_string = ""
for app in supported_apps:
## Dictionary for nose arguments
args_dict = dict()
try:
# Application might not support speficied test_method
try:
args_dict['test_method'] = supported_apps[app][test_method]
except KeyError:
continue
args_dict['app_name'] = app
args_dict['test_file'] = supported_apps[app]['test_file']
except KeyError:
print "Test Method not not found"
print "Are you sure it is specified correctly in runNose.py?"
raise RuntimeError
nose_args = """ {app_name}/{test_file}:{test_method} """.format(**args_dict)
cmd_string += nose_args
return cmd_string
def parse_app(appTest):
"""
@param appTest: User argument defining what module.case to run.
"""
supported_apps = generate_constants()
args_dict = dict()
test_method = None
nose_args = None
app_test = appTest.split(".")
app_or_test = app_test[0]
# Add test method to nose args
if "_Test" in app_or_test:
test_method = app_or_test
nose_args = generate_for_method(test_method)
return nose_args
# Add single application to nose args
args_dict['app_name'] = app_or_test
try:
args_dict['test_file'] = supported_apps[app_or_test]['test_file']
except KeyError:
print "Invalid application name: %s" % app_or_test
raise RuntimeError
## Add application specific test method
args_dict['test_method'] = ""
if len(app_test) == 2:
test_method = app_test[1]
try:
args_dict['test_method'] = supported_apps[app_or_test][test_method]
except KeyError:
print "Invalid test method name: %s" % test_method
raise RuntimeError
nose_args = """ {app_name}/{test_file}:{test_method} """.format(**args_dict)
print nose_args
return nose_args
def runTestGen(testGenPath, verbose):
## So we can get back
binPath = os.getcwd()
supported_apps = generate_constants()
# Change open all supported applications and run testGen
for app in supported_apps:
appPath = "{BUILD_ROOT}/Autocoders/Python/test/{APP_DIR}".format(BUILD_ROOT=os.environ.get('BUILD_ROOT'), APP_DIR=app)
logging.debug("Entering: %s" % appPath)
os.chdir(appPath)
logging.debug("Calling TestGen")
v = ''
if verbose:
v = '-v'
logging.info("Test Modules will be generated with verbosity turned on")
test_gen_cmd = 'python {TEST_GEN} {verbose} pexpect_config.xml'.format(TEST_GEN=testGenPath, verbose=v)
logging.debug("Calling: %s" % test_gen_cmd)
subprocess.call(test_gen_cmd, shell=True)
os.chdir(binPath)
def cleanTestGen():
binPath = os.getcwd()
supported_apps = generate_constants()
# Change open all supported applications and run testGen
for app in supported_apps:
appPath = "{BUILD_ROOT}/Autocoders/Python/test/{APP_DIR}".format(BUILD_ROOT=os.environ.get('BUILD_ROOT'), APP_DIR=app)
logging.debug("Entering: %s" % appPath)
os.chdir(appPath)
test_file = supported_apps[app]['test_file']
logging.debug("Removing TestModule: %s" % test_file)
subprocess.call('rm {TEST_FILE}'.format(TEST_FILE=test_file), shell=True)
os.chdir(binPath)
def run_nose(nose_call):
"""
@param nose_call:
Execute nose
"""
# Change directory to Autocoders/Python/test
os.chdir("{BUILD_ROOT}/Autocoders/Python/test".format(BUILD_ROOT=os.environ.get('BUILD_ROOT')))
print "\n\n--------------- Calling NoseTest ---------------\n %s\n" % nose_call
print "--------------- Test List ---------------"
subprocess.call(nose_call, shell=True)
# Reset directory
os.chdir("{BUILD_ROOT}/Autocoders/Python/".format(BUILD_ROOT=os.environ.get('BUILD_ROOT')))
def init_parser():
"""
Initalize parser and description.
"""
app_list = get_app_list()
des = """\
Test Suite Utility
''''''''''''''''''
README located in Autocoders/Python/utils/Nosetests
Supported applications and their
tests are specified below. To test
all, run with no arguments. To run
a specific application and/or test
run with this format:
Generic Ex:
runNose.py app_name.test_method
Specific Ex:
runNose.py app1.Make_Test
----------------------------------
Apps and their tests are accumulated.
So the following arguments are valid:
runNose.py app1 app2 active_tester.Sync_Input_Test active_tester.Async_Input_Test
This will test everything in app1 and app2,
but only Sync_Input_Test and Async_Input_Test in active_tester."""
parser = argparse.ArgumentParser(description = des,
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=app_list)
parser.add_argument('-v', help="Increase verbosity", action="store_true")
parser.add_argument('applications', nargs='*', help="A list of applications to test.")
return parser
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
## Setup Paths
BUILD_ROOT = os.environ.get('BUILD_ROOT')
testGenPath = os.path.join(BUILD_ROOT, 'Autocoders/Python/utils/NoseTests/TestGenerator.py')
Parser = init_parser()
args = Parser.parse_args()
## Get Verbosity
verbose = args.v
logging.debug("Test Verbose: %s" % verbose)
## Generate TestModules
runTestGen(testGenPath, verbose)
try:
nose_call = process_args(args)
except RuntimeError:
print "Aborting."
sys.exit()
run_nose(nose_call)
## Remove generated test files
cleanTestGen()