1d9944da2SValeriy Savchenko#!/usr/bin/env python 2d9944da2SValeriy Savchenko 3d9944da2SValeriy Savchenkoimport argparse 4d9944da2SValeriy Savchenkoimport sys 53770f5c9SValeriy Savchenkoimport os 63770f5c9SValeriy Savchenko 7e30706afSValeriy Savchenkofrom subprocess import call 83770f5c9SValeriy Savchenko 93770f5c9SValeriy SavchenkoSCRIPTS_DIR = os.path.dirname(os.path.realpath(__file__)) 103770f5c9SValeriy SavchenkoPROJECTS_DIR = os.path.join(SCRIPTS_DIR, "projects") 11*dd3c26a0STobias HietaDEFAULT_LLVM_DIR = os.path.realpath( 12*dd3c26a0STobias Hieta os.path.join(SCRIPTS_DIR, os.path.pardir, os.path.pardir, os.path.pardir) 13*dd3c26a0STobias Hieta) 14d9944da2SValeriy Savchenko 15d9944da2SValeriy Savchenko 16d9944da2SValeriy Savchenkodef add(parser, args): 1794f0eb83SValeriy Savchenko import SATestAdd 1894f0eb83SValeriy Savchenko from ProjectMap import ProjectInfo 1994f0eb83SValeriy Savchenko 20d9944da2SValeriy Savchenko if args.source == "git" and (args.origin == "" or args.commit == ""): 21*dd3c26a0STobias Hieta parser.error("Please provide both --origin and --commit if source is 'git'") 22d9944da2SValeriy Savchenko 23d9944da2SValeriy Savchenko if args.source != "git" and (args.origin != "" or args.commit != ""): 24*dd3c26a0STobias Hieta parser.error( 25*dd3c26a0STobias Hieta "Options --origin and --commit don't make sense when " "source is not 'git'" 26*dd3c26a0STobias Hieta ) 27d9944da2SValeriy Savchenko 28*dd3c26a0STobias Hieta project = ProjectInfo( 29*dd3c26a0STobias Hieta args.name[0], args.mode, args.source, args.origin, args.commit 30*dd3c26a0STobias Hieta ) 31d9944da2SValeriy Savchenko 32d9944da2SValeriy Savchenko SATestAdd.add_new_project(project) 33d9944da2SValeriy Savchenko 34d9944da2SValeriy Savchenko 35d9944da2SValeriy Savchenkodef build(parser, args): 3694f0eb83SValeriy Savchenko import SATestBuild 3794f0eb83SValeriy Savchenko 38d9944da2SValeriy Savchenko SATestBuild.VERBOSE = args.verbose 3938b455e9SValeriy Savchenko 40aec12c12SValeriy Savchenko projects = get_projects(parser, args) 41*dd3c26a0STobias Hieta tester = SATestBuild.RegressionTester( 42*dd3c26a0STobias Hieta args.jobs, 4338b455e9SValeriy Savchenko projects, 4438b455e9SValeriy Savchenko args.override_compiler, 45d9944da2SValeriy Savchenko args.extra_analyzer_config, 46198e6771SDeep Majumder args.extra_checkers, 47d9944da2SValeriy Savchenko args.regenerate, 48*dd3c26a0STobias Hieta args.strictness, 49*dd3c26a0STobias Hieta ) 50d9944da2SValeriy Savchenko tests_passed = tester.test_all() 51d9944da2SValeriy Savchenko 52d9944da2SValeriy Savchenko if not tests_passed: 53d9944da2SValeriy Savchenko sys.stderr.write("ERROR: Tests failed.\n") 54d9944da2SValeriy Savchenko sys.exit(42) 55d9944da2SValeriy Savchenko 56d9944da2SValeriy Savchenko 57d9944da2SValeriy Savchenkodef compare(parser, args): 5894f0eb83SValeriy Savchenko import CmpRuns 5994f0eb83SValeriy Savchenko 60*dd3c26a0STobias Hieta choices = [ 61*dd3c26a0STobias Hieta CmpRuns.HistogramType.RELATIVE.value, 6294f0eb83SValeriy Savchenko CmpRuns.HistogramType.LOG_RELATIVE.value, 63*dd3c26a0STobias Hieta CmpRuns.HistogramType.ABSOLUTE.value, 64*dd3c26a0STobias Hieta ] 6594f0eb83SValeriy Savchenko 6694f0eb83SValeriy Savchenko if args.histogram is not None and args.histogram not in choices: 67*dd3c26a0STobias Hieta parser.error( 68*dd3c26a0STobias Hieta "Incorrect histogram type, available choices are {}".format(choices) 69*dd3c26a0STobias Hieta ) 7094f0eb83SValeriy Savchenko 71d9944da2SValeriy Savchenko dir_old = CmpRuns.ResultsDirectory(args.old[0], args.root_old) 72d9944da2SValeriy Savchenko dir_new = CmpRuns.ResultsDirectory(args.new[0], args.root_new) 73d9944da2SValeriy Savchenko 74*dd3c26a0STobias Hieta CmpRuns.dump_scan_build_results_diff( 75*dd3c26a0STobias Hieta dir_old, 76*dd3c26a0STobias Hieta dir_new, 77d9944da2SValeriy Savchenko show_stats=args.show_stats, 78d9944da2SValeriy Savchenko stats_only=args.stats_only, 79d9944da2SValeriy Savchenko histogram=args.histogram, 80*dd3c26a0STobias Hieta verbose_log=args.verbose_log, 81*dd3c26a0STobias Hieta ) 82d9944da2SValeriy Savchenko 83d9944da2SValeriy Savchenko 84d9944da2SValeriy Savchenkodef update(parser, args): 8594f0eb83SValeriy Savchenko import SATestUpdateDiffs 8694f0eb83SValeriy Savchenko from ProjectMap import ProjectMap 8794f0eb83SValeriy Savchenko 88d9944da2SValeriy Savchenko project_map = ProjectMap() 89d9944da2SValeriy Savchenko for project in project_map.projects: 9010851f9dSValeriy Savchenko SATestUpdateDiffs.update_reference_results(project, args.git) 91d9944da2SValeriy Savchenko 92d9944da2SValeriy Savchenko 935b4f1435SValeriy Savchenkodef benchmark(parser, args): 945b4f1435SValeriy Savchenko from SATestBenchmark import Benchmark 955b4f1435SValeriy Savchenko 96aec12c12SValeriy Savchenko projects = get_projects(parser, args) 975b4f1435SValeriy Savchenko benchmark = Benchmark(projects, args.iterations, args.output) 985b4f1435SValeriy Savchenko benchmark.run() 995b4f1435SValeriy Savchenko 1005b4f1435SValeriy Savchenko 1015b4f1435SValeriy Savchenkodef benchmark_compare(parser, args): 1025b4f1435SValeriy Savchenko import SATestBenchmark 103*dd3c26a0STobias Hieta 1045b4f1435SValeriy Savchenko SATestBenchmark.compare(args.old, args.new, args.output) 1055b4f1435SValeriy Savchenko 1065b4f1435SValeriy Savchenko 107aec12c12SValeriy Savchenkodef get_projects(parser, args): 108aec12c12SValeriy Savchenko from ProjectMap import ProjectMap, Size 1095b4f1435SValeriy Savchenko 1105b4f1435SValeriy Savchenko project_map = ProjectMap() 1115b4f1435SValeriy Savchenko projects = project_map.projects 1125b4f1435SValeriy Savchenko 113aec12c12SValeriy Savchenko def filter_projects(projects, predicate, force=False): 114*dd3c26a0STobias Hieta return [ 115*dd3c26a0STobias Hieta project.with_fields( 116*dd3c26a0STobias Hieta enabled=(force or project.enabled) and predicate(project) 117*dd3c26a0STobias Hieta ) 118*dd3c26a0STobias Hieta for project in projects 119*dd3c26a0STobias Hieta ] 120aec12c12SValeriy Savchenko 121aec12c12SValeriy Savchenko if args.projects: 122aec12c12SValeriy Savchenko projects_arg = args.projects.split(",") 123*dd3c26a0STobias Hieta available_projects = [project.name for project in projects] 1245b4f1435SValeriy Savchenko 1255b4f1435SValeriy Savchenko # validate that given projects are present in the project map file 1265b4f1435SValeriy Savchenko for manual_project in projects_arg: 1275b4f1435SValeriy Savchenko if manual_project not in available_projects: 128*dd3c26a0STobias Hieta parser.error( 129*dd3c26a0STobias Hieta "Project '{project}' is not found in " 1305b4f1435SValeriy Savchenko "the project map file. Available projects are " 131*dd3c26a0STobias Hieta "{all}.".format(project=manual_project, all=available_projects) 132*dd3c26a0STobias Hieta ) 1335b4f1435SValeriy Savchenko 134*dd3c26a0STobias Hieta projects = filter_projects( 135*dd3c26a0STobias Hieta projects, lambda project: project.name in projects_arg, force=True 136*dd3c26a0STobias Hieta ) 137aec12c12SValeriy Savchenko 138aec12c12SValeriy Savchenko try: 139aec12c12SValeriy Savchenko max_size = Size.from_str(args.max_size) 140aec12c12SValeriy Savchenko except ValueError as e: 141aec12c12SValeriy Savchenko parser.error("{}".format(e)) 142aec12c12SValeriy Savchenko 143*dd3c26a0STobias Hieta projects = filter_projects(projects, lambda project: project.size <= max_size) 1445b4f1435SValeriy Savchenko 1455b4f1435SValeriy Savchenko return projects 1465b4f1435SValeriy Savchenko 1475b4f1435SValeriy Savchenko 1483770f5c9SValeriy Savchenkodef docker(parser, args): 1493770f5c9SValeriy Savchenko if len(args.rest) > 0: 1503770f5c9SValeriy Savchenko if args.rest[0] != "--": 1513770f5c9SValeriy Savchenko parser.error("REST arguments should start with '--'") 1523770f5c9SValeriy Savchenko args.rest = args.rest[1:] 1533770f5c9SValeriy Savchenko 1543770f5c9SValeriy Savchenko if args.build_image: 1553770f5c9SValeriy Savchenko docker_build_image() 15611f28782SValeriy Savchenko elif args.shell: 15711f28782SValeriy Savchenko docker_shell(args) 1583770f5c9SValeriy Savchenko else: 159*dd3c26a0STobias Hieta sys.exit(docker_run(args, " ".join(args.rest))) 1603770f5c9SValeriy Savchenko 1613770f5c9SValeriy Savchenko 1623770f5c9SValeriy Savchenkodef docker_build_image(): 163*dd3c26a0STobias Hieta sys.exit(call("docker build --tag satest-image {}".format(SCRIPTS_DIR), shell=True)) 1643770f5c9SValeriy Savchenko 1653770f5c9SValeriy Savchenko 16611f28782SValeriy Savchenkodef docker_shell(args): 16711f28782SValeriy Savchenko try: 16811f28782SValeriy Savchenko # First we need to start the docker container in a waiting mode, 16911f28782SValeriy Savchenko # so it doesn't do anything, but most importantly keeps working 17011f28782SValeriy Savchenko # while the shell session is in progress. 17111f28782SValeriy Savchenko docker_run(args, "--wait", "--detach") 17211f28782SValeriy Savchenko # Since the docker container is running, we can actually connect to it 17311f28782SValeriy Savchenko call("docker exec -it satest bash", shell=True) 17411f28782SValeriy Savchenko 17511f28782SValeriy Savchenko except KeyboardInterrupt: 17611f28782SValeriy Savchenko pass 17711f28782SValeriy Savchenko 17811f28782SValeriy Savchenko finally: 1799c7ff0a4SValeriy Savchenko docker_cleanup() 18011f28782SValeriy Savchenko 18111f28782SValeriy Savchenko 18211f28782SValeriy Savchenkodef docker_run(args, command, docker_args=""): 1839c7ff0a4SValeriy Savchenko try: 184*dd3c26a0STobias Hieta return call( 185*dd3c26a0STobias Hieta "docker run --rm --name satest " 1863770f5c9SValeriy Savchenko "-v {llvm}:/llvm-project " 1873770f5c9SValeriy Savchenko "-v {build}:/build " 1883770f5c9SValeriy Savchenko "-v {clang}:/analyzer " 1893770f5c9SValeriy Savchenko "-v {scripts}:/scripts " 1903770f5c9SValeriy Savchenko "-v {projects}:/projects " 19111f28782SValeriy Savchenko "{docker_args} " 192*dd3c26a0STobias Hieta "satest-image:latest {command}".format( 193*dd3c26a0STobias Hieta llvm=args.llvm_project_dir, 194e30706afSValeriy Savchenko build=args.build_dir, 195e30706afSValeriy Savchenko clang=args.clang_dir, 196e30706afSValeriy Savchenko scripts=SCRIPTS_DIR, 197e30706afSValeriy Savchenko projects=PROJECTS_DIR, 19811f28782SValeriy Savchenko docker_args=docker_args, 199*dd3c26a0STobias Hieta command=command, 200*dd3c26a0STobias Hieta ), 201*dd3c26a0STobias Hieta shell=True, 202*dd3c26a0STobias Hieta ) 2033770f5c9SValeriy Savchenko 2049c7ff0a4SValeriy Savchenko except KeyboardInterrupt: 2059c7ff0a4SValeriy Savchenko docker_cleanup() 2069c7ff0a4SValeriy Savchenko 2079c7ff0a4SValeriy Savchenko 2089c7ff0a4SValeriy Savchenkodef docker_cleanup(): 2099c7ff0a4SValeriy Savchenko print("Please wait for docker to clean up") 2109c7ff0a4SValeriy Savchenko call("docker stop satest", shell=True) 2119c7ff0a4SValeriy Savchenko 2123770f5c9SValeriy Savchenko 213d9944da2SValeriy Savchenkodef main(): 214d9944da2SValeriy Savchenko parser = argparse.ArgumentParser() 215d9944da2SValeriy Savchenko subparsers = parser.add_subparsers() 216d9944da2SValeriy Savchenko 217d9944da2SValeriy Savchenko # add subcommand 218d9944da2SValeriy Savchenko add_parser = subparsers.add_parser( 219*dd3c26a0STobias Hieta "add", help="Add a new project for the analyzer testing." 220*dd3c26a0STobias Hieta ) 221d9944da2SValeriy Savchenko # TODO: Add an option not to build. 222d9944da2SValeriy Savchenko # TODO: Set the path to the Repository directory. 223d9944da2SValeriy Savchenko add_parser.add_argument("name", nargs=1, help="Name of the new project") 224*dd3c26a0STobias Hieta add_parser.add_argument( 225*dd3c26a0STobias Hieta "--mode", 226*dd3c26a0STobias Hieta action="store", 227*dd3c26a0STobias Hieta default=1, 228*dd3c26a0STobias Hieta type=int, 229d9944da2SValeriy Savchenko choices=[0, 1, 2], 230d9944da2SValeriy Savchenko help="Build mode: 0 for single file project, " 231d9944da2SValeriy Savchenko "1 for scan_build, " 232*dd3c26a0STobias Hieta "2 for single file c++11 project", 233*dd3c26a0STobias Hieta ) 234*dd3c26a0STobias Hieta add_parser.add_argument( 235*dd3c26a0STobias Hieta "--source", 236*dd3c26a0STobias Hieta action="store", 237*dd3c26a0STobias Hieta default="script", 238d9944da2SValeriy Savchenko choices=["script", "git", "zip"], 239d9944da2SValeriy Savchenko help="Source type of the new project: " 240d9944da2SValeriy Savchenko "'git' for getting from git " 241d9944da2SValeriy Savchenko "(please provide --origin and --commit), " 242d9944da2SValeriy Savchenko "'zip' for unpacking source from a zip file, " 243d9944da2SValeriy Savchenko "'script' for downloading source by running " 244*dd3c26a0STobias Hieta "a custom script", 245*dd3c26a0STobias Hieta ) 246*dd3c26a0STobias Hieta add_parser.add_argument( 247*dd3c26a0STobias Hieta "--origin", action="store", default="", help="Origin link for a git repository" 248*dd3c26a0STobias Hieta ) 249*dd3c26a0STobias Hieta add_parser.add_argument( 250*dd3c26a0STobias Hieta "--commit", action="store", default="", help="Git hash for a commit to checkout" 251*dd3c26a0STobias Hieta ) 252d9944da2SValeriy Savchenko add_parser.set_defaults(func=add) 253d9944da2SValeriy Savchenko 254d9944da2SValeriy Savchenko # build subcommand 255d9944da2SValeriy Savchenko build_parser = subparsers.add_parser( 256d9944da2SValeriy Savchenko "build", 257d9944da2SValeriy Savchenko help="Build projects from the project map and compare results with " 258*dd3c26a0STobias Hieta "the reference.", 259*dd3c26a0STobias Hieta ) 260*dd3c26a0STobias Hieta build_parser.add_argument( 261*dd3c26a0STobias Hieta "--strictness", 262*dd3c26a0STobias Hieta dest="strictness", 263*dd3c26a0STobias Hieta type=int, 264*dd3c26a0STobias Hieta default=0, 265d9944da2SValeriy Savchenko help="0 to fail on runtime errors, 1 to fail " 266d9944da2SValeriy Savchenko "when the number of found bugs are different " 267d9944da2SValeriy Savchenko "from the reference, 2 to fail on any " 268*dd3c26a0STobias Hieta "difference from the reference. Default is 0.", 269*dd3c26a0STobias Hieta ) 270*dd3c26a0STobias Hieta build_parser.add_argument( 271*dd3c26a0STobias Hieta "-r", 272*dd3c26a0STobias Hieta dest="regenerate", 273*dd3c26a0STobias Hieta action="store_true", 274d9944da2SValeriy Savchenko default=False, 275*dd3c26a0STobias Hieta help="Regenerate reference output.", 276*dd3c26a0STobias Hieta ) 277*dd3c26a0STobias Hieta build_parser.add_argument( 278*dd3c26a0STobias Hieta "--override-compiler", 279*dd3c26a0STobias Hieta action="store_true", 280*dd3c26a0STobias Hieta default=False, 281*dd3c26a0STobias Hieta help="Call scan-build with " "--override-compiler option.", 282*dd3c26a0STobias Hieta ) 283*dd3c26a0STobias Hieta build_parser.add_argument( 284*dd3c26a0STobias Hieta "-j", 285*dd3c26a0STobias Hieta "--jobs", 286*dd3c26a0STobias Hieta dest="jobs", 287*dd3c26a0STobias Hieta type=int, 288*dd3c26a0STobias Hieta default=0, 289*dd3c26a0STobias Hieta help="Number of projects to test concurrently", 290*dd3c26a0STobias Hieta ) 291*dd3c26a0STobias Hieta build_parser.add_argument( 292*dd3c26a0STobias Hieta "--extra-analyzer-config", 293*dd3c26a0STobias Hieta dest="extra_analyzer_config", 294*dd3c26a0STobias Hieta type=str, 295d9944da2SValeriy Savchenko default="", 296*dd3c26a0STobias Hieta help="Arguments passed to to -analyzer-config", 297*dd3c26a0STobias Hieta ) 298*dd3c26a0STobias Hieta build_parser.add_argument( 299*dd3c26a0STobias Hieta "--extra-checkers", 300*dd3c26a0STobias Hieta dest="extra_checkers", 301*dd3c26a0STobias Hieta type=str, 302198e6771SDeep Majumder default="", 303*dd3c26a0STobias Hieta help="Extra checkers to enable", 304*dd3c26a0STobias Hieta ) 305*dd3c26a0STobias Hieta build_parser.add_argument( 306*dd3c26a0STobias Hieta "--projects", 307*dd3c26a0STobias Hieta action="store", 308*dd3c26a0STobias Hieta default="", 309*dd3c26a0STobias Hieta help="Comma-separated list of projects to test", 310*dd3c26a0STobias Hieta ) 311*dd3c26a0STobias Hieta build_parser.add_argument( 312*dd3c26a0STobias Hieta "--max-size", 313*dd3c26a0STobias Hieta action="store", 314*dd3c26a0STobias Hieta default=None, 315*dd3c26a0STobias Hieta help="Maximum size for the projects to test", 316*dd3c26a0STobias Hieta ) 317d9944da2SValeriy Savchenko build_parser.add_argument("-v", "--verbose", action="count", default=0) 318d9944da2SValeriy Savchenko build_parser.set_defaults(func=build) 319d9944da2SValeriy Savchenko 320d9944da2SValeriy Savchenko # compare subcommand 321d9944da2SValeriy Savchenko cmp_parser = subparsers.add_parser( 322d9944da2SValeriy Savchenko "compare", 323d9944da2SValeriy Savchenko help="Comparing two static analyzer runs in terms of " 324*dd3c26a0STobias Hieta "reported warnings and execution time statistics.", 325*dd3c26a0STobias Hieta ) 326*dd3c26a0STobias Hieta cmp_parser.add_argument( 327*dd3c26a0STobias Hieta "--root-old", 328*dd3c26a0STobias Hieta dest="root_old", 329*dd3c26a0STobias Hieta help="Prefix to ignore on source files for " "OLD directory", 330*dd3c26a0STobias Hieta action="store", 331*dd3c26a0STobias Hieta type=str, 332*dd3c26a0STobias Hieta default="", 333*dd3c26a0STobias Hieta ) 334*dd3c26a0STobias Hieta cmp_parser.add_argument( 335*dd3c26a0STobias Hieta "--root-new", 336*dd3c26a0STobias Hieta dest="root_new", 337*dd3c26a0STobias Hieta help="Prefix to ignore on source files for " "NEW directory", 338*dd3c26a0STobias Hieta action="store", 339*dd3c26a0STobias Hieta type=str, 340*dd3c26a0STobias Hieta default="", 341*dd3c26a0STobias Hieta ) 342*dd3c26a0STobias Hieta cmp_parser.add_argument( 343*dd3c26a0STobias Hieta "--verbose-log", 344*dd3c26a0STobias Hieta dest="verbose_log", 345*dd3c26a0STobias Hieta help="Write additional information to LOG " "[default=None]", 346*dd3c26a0STobias Hieta action="store", 347*dd3c26a0STobias Hieta type=str, 348*dd3c26a0STobias Hieta default=None, 349*dd3c26a0STobias Hieta metavar="LOG", 350*dd3c26a0STobias Hieta ) 351*dd3c26a0STobias Hieta cmp_parser.add_argument( 352*dd3c26a0STobias Hieta "--stats-only", 353*dd3c26a0STobias Hieta action="store_true", 354*dd3c26a0STobias Hieta dest="stats_only", 355*dd3c26a0STobias Hieta default=False, 356*dd3c26a0STobias Hieta help="Only show statistics on reports", 357*dd3c26a0STobias Hieta ) 358*dd3c26a0STobias Hieta cmp_parser.add_argument( 359*dd3c26a0STobias Hieta "--show-stats", 360*dd3c26a0STobias Hieta action="store_true", 361*dd3c26a0STobias Hieta dest="show_stats", 362*dd3c26a0STobias Hieta default=False, 363*dd3c26a0STobias Hieta help="Show change in statistics", 364*dd3c26a0STobias Hieta ) 365*dd3c26a0STobias Hieta cmp_parser.add_argument( 366*dd3c26a0STobias Hieta "--histogram", 367*dd3c26a0STobias Hieta action="store", 368*dd3c26a0STobias Hieta default=None, 369*dd3c26a0STobias Hieta help="Show histogram of paths differences. " "Requires matplotlib", 370*dd3c26a0STobias Hieta ) 371d9944da2SValeriy Savchenko cmp_parser.add_argument("old", nargs=1, help="Directory with old results") 372d9944da2SValeriy Savchenko cmp_parser.add_argument("new", nargs=1, help="Directory with new results") 373d9944da2SValeriy Savchenko cmp_parser.set_defaults(func=compare) 374d9944da2SValeriy Savchenko 375d9944da2SValeriy Savchenko # update subcommand 376d9944da2SValeriy Savchenko upd_parser = subparsers.add_parser( 377d9944da2SValeriy Savchenko "update", 378d9944da2SValeriy Savchenko help="Update static analyzer reference results based on the previous " 379*dd3c26a0STobias Hieta "run of SATest build. Assumes that SATest build was just run.", 380*dd3c26a0STobias Hieta ) 381*dd3c26a0STobias Hieta upd_parser.add_argument( 382*dd3c26a0STobias Hieta "--git", action="store_true", help="Stage updated results using git." 383*dd3c26a0STobias Hieta ) 384d9944da2SValeriy Savchenko upd_parser.set_defaults(func=update) 385d9944da2SValeriy Savchenko 3863770f5c9SValeriy Savchenko # docker subcommand 3873770f5c9SValeriy Savchenko dock_parser = subparsers.add_parser( 388*dd3c26a0STobias Hieta "docker", help="Run regression system in the docker." 389*dd3c26a0STobias Hieta ) 3903770f5c9SValeriy Savchenko 391*dd3c26a0STobias Hieta dock_parser.add_argument( 392*dd3c26a0STobias Hieta "--build-image", 393*dd3c26a0STobias Hieta action="store_true", 394*dd3c26a0STobias Hieta help="Build docker image for running tests.", 395*dd3c26a0STobias Hieta ) 396*dd3c26a0STobias Hieta dock_parser.add_argument( 397*dd3c26a0STobias Hieta "--shell", action="store_true", help="Start a shell on docker." 398*dd3c26a0STobias Hieta ) 399*dd3c26a0STobias Hieta dock_parser.add_argument( 400*dd3c26a0STobias Hieta "--llvm-project-dir", 401*dd3c26a0STobias Hieta action="store", 4023770f5c9SValeriy Savchenko default=DEFAULT_LLVM_DIR, 4033770f5c9SValeriy Savchenko help="Path to LLVM source code. Defaults " 404*dd3c26a0STobias Hieta "to the repo where this script is located. ", 405*dd3c26a0STobias Hieta ) 406*dd3c26a0STobias Hieta dock_parser.add_argument( 407*dd3c26a0STobias Hieta "--build-dir", 408*dd3c26a0STobias Hieta action="store", 409*dd3c26a0STobias Hieta default="", 410*dd3c26a0STobias Hieta help="Path to a directory where docker should " "build LLVM code.", 411*dd3c26a0STobias Hieta ) 412*dd3c26a0STobias Hieta dock_parser.add_argument( 413*dd3c26a0STobias Hieta "--clang-dir", 414*dd3c26a0STobias Hieta action="store", 415*dd3c26a0STobias Hieta default="", 416*dd3c26a0STobias Hieta help="Path to find/install LLVM installation.", 417*dd3c26a0STobias Hieta ) 418*dd3c26a0STobias Hieta dock_parser.add_argument( 419*dd3c26a0STobias Hieta "rest", 420*dd3c26a0STobias Hieta nargs=argparse.REMAINDER, 421*dd3c26a0STobias Hieta default=[], 422*dd3c26a0STobias Hieta help="Additional args that will be forwarded " "to the docker's entrypoint.", 423*dd3c26a0STobias Hieta ) 4243770f5c9SValeriy Savchenko dock_parser.set_defaults(func=docker) 4253770f5c9SValeriy Savchenko 4265b4f1435SValeriy Savchenko # benchmark subcommand 4275b4f1435SValeriy Savchenko bench_parser = subparsers.add_parser( 428*dd3c26a0STobias Hieta "benchmark", help="Run benchmarks by building a set of projects multiple times." 429*dd3c26a0STobias Hieta ) 4305b4f1435SValeriy Savchenko 431*dd3c26a0STobias Hieta bench_parser.add_argument( 432*dd3c26a0STobias Hieta "-i", 433*dd3c26a0STobias Hieta "--iterations", 434*dd3c26a0STobias Hieta action="store", 435*dd3c26a0STobias Hieta type=int, 436*dd3c26a0STobias Hieta default=20, 437*dd3c26a0STobias Hieta help="Number of iterations for building each " "project.", 438*dd3c26a0STobias Hieta ) 439*dd3c26a0STobias Hieta bench_parser.add_argument( 440*dd3c26a0STobias Hieta "-o", 441*dd3c26a0STobias Hieta "--output", 442*dd3c26a0STobias Hieta action="store", 4435b4f1435SValeriy Savchenko default="benchmark.csv", 444*dd3c26a0STobias Hieta help="Output csv file for the benchmark results", 445*dd3c26a0STobias Hieta ) 446*dd3c26a0STobias Hieta bench_parser.add_argument( 447*dd3c26a0STobias Hieta "--projects", 448*dd3c26a0STobias Hieta action="store", 449*dd3c26a0STobias Hieta default="", 450*dd3c26a0STobias Hieta help="Comma-separated list of projects to test", 451*dd3c26a0STobias Hieta ) 452*dd3c26a0STobias Hieta bench_parser.add_argument( 453*dd3c26a0STobias Hieta "--max-size", 454*dd3c26a0STobias Hieta action="store", 455*dd3c26a0STobias Hieta default=None, 456*dd3c26a0STobias Hieta help="Maximum size for the projects to test", 457*dd3c26a0STobias Hieta ) 4585b4f1435SValeriy Savchenko bench_parser.set_defaults(func=benchmark) 4595b4f1435SValeriy Savchenko 4605b4f1435SValeriy Savchenko bench_subparsers = bench_parser.add_subparsers() 4615b4f1435SValeriy Savchenko bench_compare_parser = bench_subparsers.add_parser( 462*dd3c26a0STobias Hieta "compare", help="Compare benchmark runs." 463*dd3c26a0STobias Hieta ) 464*dd3c26a0STobias Hieta bench_compare_parser.add_argument( 465*dd3c26a0STobias Hieta "--old", 466*dd3c26a0STobias Hieta action="store", 467*dd3c26a0STobias Hieta required=True, 468*dd3c26a0STobias Hieta help="Benchmark reference results to " "compare agains.", 469*dd3c26a0STobias Hieta ) 470*dd3c26a0STobias Hieta bench_compare_parser.add_argument( 471*dd3c26a0STobias Hieta "--new", action="store", required=True, help="New benchmark results to check." 472*dd3c26a0STobias Hieta ) 473*dd3c26a0STobias Hieta bench_compare_parser.add_argument( 474*dd3c26a0STobias Hieta "-o", "--output", action="store", required=True, help="Output file for plots." 475*dd3c26a0STobias Hieta ) 4765b4f1435SValeriy Savchenko bench_compare_parser.set_defaults(func=benchmark_compare) 4775b4f1435SValeriy Savchenko 478d9944da2SValeriy Savchenko args = parser.parse_args() 479d9944da2SValeriy Savchenko args.func(parser, args) 480d9944da2SValeriy Savchenko 481d9944da2SValeriy Savchenko 482d9944da2SValeriy Savchenkoif __name__ == "__main__": 483d9944da2SValeriy Savchenko main() 484