This change gets us cleaner, more readable argument parsing code. Another advantage of this approach is that it automatically generates help menus, which means options will not be implemented without a help entry (like --resume)
V2: - Does not remove deprecated options, only marks them as deprecated V3: - Fixes deprecated warning for tests from V2 always being triggered Signed-off-by: Dylan Baker <baker.dyla...@gmail.com> --- piglit-print-commands.py | 98 +++++++------------ piglit-run.py | 249 +++++++++++++++++++++++------------------------ 2 files changed, 159 insertions(+), 188 deletions(-) diff --git a/piglit-print-commands.py b/piglit-print-commands.py index 3479ef1..9dd2290 100755 --- a/piglit-print-commands.py +++ b/piglit-print-commands.py @@ -22,7 +22,7 @@ # DEALINGS IN THE SOFTWARE. -from getopt import getopt, GetoptError +import argparse import os.path as path import re import sys, os @@ -38,77 +38,51 @@ from framework.gleantest import GleanTest ############################################################################# ##### Main program ############################################################################# -def usage(): - USAGE = """\ -Usage: %(progName)s [options] [profile.tests] - -Prints a list of all the tests and how to run them. Ex: - piglit test name ::: /path/to/piglit/bin/program <args> - glean test name ::: PIGLIT_TEST='...' /path/to/piglit/bin/glean -v -v -v ... - -Options: - -h, --help Show this message - -t regexp, --include-tests=regexp Run only matching tests (can be used more - than once) - --tests=regexp Run only matching tests (can be used more - than once) DEPRICATED use --include-tests instead - -x regexp, --exclude-tests=regexp Exclude matching tests (can be used - more than once) -Example: - %(progName)s tests/all.tests - %(progName)s -t basic tests/all.tests - Print tests whose path contains the word 'basic' - - %(progName)s -t ^glean/ -t tex tests/all.tests - Print tests that are in the 'glean' group or whose path contains - the substring 'tex' -""" - print USAGE % {'progName': sys.argv[0]} - sys.exit(1) def main(): - env = core.Environment() + parser = argparse.ArgumentParser(sys.argv) + + parser.add_argument("-t", "--include-tests", + default = [], + action = "append", + metavar = "<regex>", + help = "Run only matching tests (can be used more than once)") + parser.add_argument("--tests", + default = [], + action = "append", + metavar = "<regex>", + help = "Run only matching tests (can be used more than once)" \ + "Deprecated") + parser.add_argument("-x", "--exclude-tests", + default = [], + action = "append", + metavar = "<regex>", + help = "Exclude matching tests (can be used more than once)") + parser.add_argument("testProfile", + metavar = "<Path to testfile>", + help = "Path to results folder") + + args = parser.parse_args() - try: - option_list = [ - "help", - "tests=", - "include-tests=", - "exclude-tests=", - ] - options, args = getopt(sys.argv[1:], "ht:x:", option_list) - except GetoptError: - usage() - - OptionName = '' - test_filter = [] - exclude_filter = [] - - for name, value in options: - if name in ('-h', '--help'): - usage() - elif name in ('-t', '--include-tests'): - test_filter.append(value) - env.filter.append(re.compile(value)) - elif name in ('--tests'): - test_filter.append(value) - env.filter.append(re.compile(value)) - print "Warning: Option --tets is deprecated, " \ - "use --include-tests instead" - elif name in ('-x', '--exclude-tests'): - exclude_filter.append(value) - env.exclude_filter.append(re.compile(value)) + env = core.Environment() - if len(args) != 1: - usage() + # If --tests is called warn that it is deprecated + if args.tests is no []: + print "Warning: Option --tests is deprecated. Use --include-tests" - profileFilename = args[0] + # Append includes and excludes to env + for each in args.include_tests: + env.filter.append(re.compile(each)) + for each in args.tests: + env.filter.append(re.compile(each)) + for each in args.exclude_tests: + env.exclude_filter.append(re.compile(each)) # Change to the piglit's path piglit_dir = path.dirname(path.realpath(sys.argv[0])) os.chdir(piglit_dir) - profile = core.loadTestProfile(profileFilename) + profile = core.loadTestProfile(args.testFile) def getCommand(test): command = '' diff --git a/piglit-run.py b/piglit-run.py index 599981d..2d0afc1 100755 --- a/piglit-run.py +++ b/piglit-run.py @@ -22,7 +22,7 @@ # DEALINGS IN THE SOFTWARE. -from getopt import getopt, GetoptError +import argparse import os.path as path import re import sys, os @@ -37,123 +37,112 @@ from framework.threads import synchronized_self ############################################################################# ##### Main program ############################################################################# -def usage(): - USAGE = """\ -Usage: %(progName)s [options] [profile.tests] [results] - %(progName)s [options] -r [results] - -Options: - -h, --help Show this message - -d, --dry-run Do not execute the tests - -t regexp, --include-tests=regexp Run only matching tests (can be used more - than once) - --tests=regexp Run only matching tests (can be used more - than once) DEPRICATED: use --include-tests instead - -x regexp, --exclude-tests=regexp Excludey matching tests (can be used - more than once) - -n name, --name=name Name of the testrun - -c bool, --concurrent= Enable/disable concurrent test runs. Valid - option values are: 0, 1, on, off. (default: on) - DEPRICATED: use --no-concurrency to turn - concurrent test runs off - --no-concurrency Disables concurrent test runs - --valgrind Run tests in valgrind's memcheck. - -p platform, --platform=platform Name of the piglit platform to use. - --resume Resume and interupted test run - -Example: - %(progName)s tests/all.tests results/all - Run all tests, store the results in the directory results/all - - %(progName)s -t basic tests/all.tests results/all - Run all tests whose path contains the word 'basic' - - %(progName)s -t ^glean/ -t tex tests/all.tests results/all - Run all tests that are in the 'glean' group or whose path contains - the substring 'tex' - - %(progName)s -r -x bad-test results/all - Resume an interrupted test run whose results are stored in the - directory results/all, skipping bad-test. -""" - print USAGE % {'progName': sys.argv[0]} - sys.exit(1) def main(): env = core.Environment() - try: - option_list = [ - "help", - "dry-run", - "resume", - "valgrind", - "include-tests=", - "tests=", - "name=", - "exclude-tests=", - "no-concurrency", - "concurrent=", - "platform=", - ] - options, args = getopt(sys.argv[1:], "hdrt:n:x:c:p:", option_list) - except GetoptError: - usage() - - OptionName = '' - OptionResume = False - test_filter = [] - exclude_filter = [] - platform = None - - for name, value in options: - if name in ('-h', '--help'): - usage() - elif name in ('-d', '--dry-run'): - env.execute = False - elif name in ('-r', '--resume'): - OptionResume = True - elif name in ('--valgrind'): - env.valgrind = True - elif name in ('-t', '--include-tests'): - test_filter.append(value) - env.filter.append(re.compile(value)) - elif name in ('--tests'): - test_filter.append(value) - env.filter.append(re.compile(value)) - print "Warning: Option --tests is deprecated, " \ - "use --include-tests instead" - elif name in ('-x', '--exclude-tests'): - exclude_filter.append(value) - env.exclude_filter.append(re.compile(value)) - elif name in ('-n', '--name'): - OptionName = value - elif name in ('--no-concurrency'): + parser = argparse.ArgumentParser(sys.argv) + + + # Either require that a name for the test is passed or that + # resume is requested + excGroup1 = parser.add_mutually_exclusive_group() + excGroup1.add_argument("-n", "--name", + metavar = "<test name>", + default = None, + help = "Name of this test run") + excGroup1.add_argument("-r", "--resume", + action = "store_true", + help = "Resume an interupted test run") + + parser.add_argument("-d", "--dry-run", + action = "store_true", + help = "Do not execute the tests") + parser.add_argument("-t", "--include-tests", + default = [], + action = "append", + metavar = "<regex>", + help = "Run only matching tests (can be used more than once)") + parser.add_argument("--tests", + default = [], + action = "append", + metavar = "<regex>", + help = "Run only matching tests (can be used more than once) " \ + "DEPRECATED: use --include-tests instead") + parser.add_argument("-x", "--exclude-tests", + default = [], + action = "append", + metavar = "<regex>", + help = "Exclude matching tests (can be used more than once)") + + # The new option going forward should be --no-concurrency, but to + # maintain backwards compatability the --c, --concurrent option should + # also be maintained. This code allows only one of the two options to be + # supplied, or it throws an error + excGroup2 = parser.add_mutually_exclusive_group() + excGroup2.add_argument("--no-concurrency", + action = "store_true", + help = "Disable concurrent test runs") + excGroup2.add_argument("-c", "--concurrent", + action = "store", + metavar = "<boolean>", + choices = ["1", "0", "on", "off"], + help = "Deprecated: Turn concrrent runs on or off") + + parser.add_argument("-p", "--platform", + choices = ["glx", "x11_egl", "wayland", "gbm"], + help = "Name of windows system passed to waffle") + parser.add_argument("--valgrind", + action = "store_true", + help = "Run tests in valgrind's memcheck") + parser.add_argument("testProfile", + metavar = "<Path to test profile>", + help = "Path to testfile to run") + parser.add_argument("resultsPath", + metavar = "<Results Path>", + help = "Path to results folder") + + args = parser.parse_args() + + + # Set the platform to pass to waffle + if args.platform is not None: + os.environ['PIGLIT_PLATFORM'] = args.platform + + # Set dry-run + if args.dry_run is True: + env.execute = False + + # Set valgrind + if args.valgrind is True: + env.valgrind = True + + # Turn concurency off if requested + # Deprecated + if args.concurrent is not None: + if (args.concurrent == '1' or args.concurrent == 'on'): + env.concurrent = True + print "Warning: Option -c, --concurrent is deprecated, " \ + "concurrent test runs are on by default" + elif (args.concurrent == '0' or args.concurrent == 'off'): env.concurrent = False - elif name in ('-c', '--concurrent'): - if value in ('1', 'on'): - env.concurrent = True - print "Warning: Option -c, --concurrent is deprecated, " \ - "concurrent test runs are on by default" - elif value in ('0', 'off'): - env.concurrent = False - print "Warning: Option -c, --concurrent is deprecated, " \ - "use --no-concurrency for non-concurrent test runs" - else: - usage() - elif name in ('-p, --platform'): - platform = value - - if platform is not None: - os.environ['PIGLIT_PLATFORM'] = platform - - if OptionResume: - if test_filter or OptionName: - print "-r is not compatible with -t or -n." - usage() - if len(args) != 1: - usage() - resultsDir = path.realpath(args[0]) + print "Warning: Option -c, --concurrent is deprecated, " \ + "use --no-concurrent for non-concurrent test runs" + # Ne need for else, since argparse restricts the arguments allowed + + # Not deprecated + elif args.no_concurrency is True: + env.concurrent = False + + # If the deprecated tests option was passed print a warning + if args.tests != []: + print "Warning: Option --tests is deprecated, use " \ + "--include-tests instead" + + # If resume is requested attempt to load the results file + # in the specified path + if args.resume is True: + resultsDir = path.realpath(args.resultsPath) # Load settings from the old results JSON old_results = core.loadTestResults(resultsDir) @@ -164,14 +153,21 @@ def main(): for value in old_results.options['exclude_filter']: exclude_filter.append(value) env.exclude_filter.append(re.compile(value)) - else: - if len(args) != 2: - usage() - profileFilename = args[0] - resultsDir = path.realpath(args[1]) - - # Change to the piglit's path + # Otherwise parse additional settings from the command line + else: + profileFilename = args.testProfile + resultsDir = args.resultsPath + + # Set the excluded and included tests regex + for each in args.include_tests: + env.filter.append(re.compile(each)) + for each in args.tests: + env.filter.append(re.compile(each)) + for each in args.exclude_tests: + env.exclude_filter.append(re.compile(each)) + + # Change working directory to the root of the piglit directory piglit_dir = path.dirname(path.realpath(sys.argv[0])) os.chdir(piglit_dir) @@ -180,10 +176,10 @@ def main(): results = core.TestrunResult() # Set results.name - if OptionName is '': - results.name = path.basename(resultsDir) + if args.name is not None: + results.name = args.name else: - results.name = OptionName + results.name = path.basename(resultsDir) # Begin json. result_filepath = os.path.join(resultsDir, 'main') @@ -196,9 +192,9 @@ def main(): json_writer.open_dict() json_writer.write_dict_item('profile', profileFilename) json_writer.write_dict_key('filter') - result_file.write(json.dumps(test_filter)) + result_file.write(json.dumps(args.include_tests)) json_writer.write_dict_key('exclude_filter') - result_file.write(json.dumps(exclude_filter)) + result_file.write(json.dumps(args.exclude_tests)) json_writer.close_dict() json_writer.write_dict_item('name', results.name) @@ -212,7 +208,7 @@ def main(): # If resuming an interrupted test run, re-write all of the existing # results since we clobbered the results file. Also, exclude them # from being run again. - if OptionResume: + if args.resume is True: for (key, value) in old_results.tests.items(): if os.path.sep != '/': key = key.replace(os.path.sep, '/', -1) @@ -236,5 +232,6 @@ def main(): print 'Thank you for running Piglit!' print 'Results have been written to ' + result_filepath + if __name__ == "__main__": main() -- 1.8.1.4 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/piglit