#! /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)
