#! /usr/bin/env python # Copyright (c) 2005 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer; # redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution; # neither the name of the copyright holders nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Steve Reinhardt import sys import os import optparse import datetime # # Regression invocation: # # regress \ # --workdir poolfs \ # --scons-opts 'BATCH=yes USE_MYSQL=no -j 30 -Q' \ # --recurse progname = os.path.basename(sys.argv[0]) optparser = optparse.OptionParser() optparser.add_option('-v', '--verbose', dest='verbose', action='store_true', default=False, help='echo commands before executing') optparser.add_option('--scratch', dest='scratch', action='store_true', default=False, help='rebuld from scratch') optparser.add_option('--builds', dest='builds', default='ALPHA_SE,ALPHA_FS,ALPHA_FS_TL', help='comma-separated list of builds to test') optparser.add_option('--variants', dest='variants', default='opt', help='comma-separated list of build variants to test') optparser.add_option('--workdir', dest='workdir', help='directory for checked-out source trees') optparser.add_option('--scons-opts', dest='scons_opts', default='', help='scons options') optparser.add_option('--no-pull', dest='pull', action='store_false', default=True, help="don't pull changes from repository") optparser.add_option('--recurse', dest='recurse', action='store_true', default=False, help='call recursively to get summary up front') (options, tests) = optparser.parse_args() # split list options on ',' to get Python lists builds = options.builds.split(',') variants = options.variants.split(',') # Repositories to clone/update repos = ['m5', 'm5-test', 'ext'] # Call os.system() and raise exception if return status is non-zero def system(cmd): if options.verbose: print cmd status = os.system(cmd) if status != 0: upper = (status & 0xff00) >> 8 lower = (status & 0xff) raise OSError, "shell command '%s' failed, status %d:%d" \ % (cmd, upper, lower) # Quote string s so it can be passed as a shell arg def shellquote(s): if ' ' in s: s = "'%s'" % s return s # The '--recurse' option invokes scons once to perform any necessary # rebuilds/test runs with the (possibly verbose) output placed in a # log file, then (if the buld was successful) returns scons to print a # summary of the results. if options.recurse: sys.argv.remove('--recurse') # avoid infinite recursion... timestr = datetime.datetime.now().isoformat('-')[:19] logfile = '%s-%s' % (progname, timestr) # quote args for shell qargs = [shellquote(a) for a in sys.argv] # always run the sub-job in verbose mode qargs.append('-v') cmd = '%s > %s 2>&1' % (' '.join(qargs), logfile) try: system(cmd) except OSError, exc: print "Error: recursive invocation failed, aborting." print exc print "=======================" os.system('cat %s' % logfile) sys.exit(1) # recursive call succeeded... re-run to generate summary # don't *re*-build from scratch now options.scratch = False # no need to re-pull since the recursive call shoudl have done that options.pull = False print "Recursive invocation successful, see %s for output." % logfile try: if options.workdir: if options.verbose: print 'cd', options.workdir os.chdir(options.workdir) if options.scratch: for dir in repos: system('rm -rf %s' % dir) system('bk clone /bk/%s' % dir) elif options.pull: for dir in repos: system('cd %s; bk pull' % dir) if not tests: print "No tests specified." sys.exit(1) if options.verbose: print 'cd m5/build' os.chdir('m5/build') targets = ['%s/test/%s/%s' % (build, variant, test) for build in builds for variant in variants for test in tests] system('scons %s %s' % (options.scons_opts, ' '.join(targets))) sys.exit(0) except OSError, exc: print "%s: " % progname, exc sys.exit(1)