DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (b66b287a2650)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
"""
Run the test(s) listed on the command line. If a directory is listed, the script will recursively
walk the directory for files named .mk and run each.

For each test, we run gmake -f test.mk. By default, make must exit with an exit code of 0, and must print 'TEST-PASS'.

Each test is run in an empty directory.

The test file may contain lines at the beginning to alter the default behavior. These are all evaluated as python:

#T commandline: ['extra', 'params', 'here']
#T returncode: 2
#T returncode-on: {'win32': 2}
#T environment: {'VAR': 'VALUE}
#T grep-for: "text"
"""

from subprocess import Popen, PIPE, STDOUT
from optparse import OptionParser
import os, re, sys, shutil

thisdir = os.path.dirname(os.path.abspath(__file__))

o = OptionParser()
o.add_option('-m', '--make',
             dest="make", default="gmake")
o.add_option('-d', '--tempdir',
             dest="tempdir", default="_mktests")
opts, args = o.parse_args()

if len(args) == 0:
    args = ['.']

makefiles = []
for a in args:
    if os.path.isfile(a):
        makefiles.append(a)
    elif os.path.isdir(a):
        for path, dirnames, filenames in os.walk(a):
            for f in filenames:
                if f.endswith('.mk'):
                    makefiles.append('%s/%s' % (path, f))
    else:
        print >>sys.stderr, "Error: Unknown file on command line"
        sys.exit(1)

tre = re.compile('^#T ([a-z-]+): (.*)$')

for makefile in makefiles:
    print "Testing: %s" % makefile,

    if os.path.exists(opts.tempdir): shutil.rmtree(opts.tempdir)
    os.mkdir(opts.tempdir, 0755)

    # For some reason, MAKEFILE_LIST uses native paths in GNU make on Windows
    # (even in MSYS!) so we pass both TESTPATH and NATIVE_TESTPATH
    cline = [opts.make, '-C', opts.tempdir, '-f', os.path.abspath(makefile), 'TESTPATH=%s' % thisdir.replace('\\','/'), 'NATIVE_TESTPATH=%s' % thisdir]
    if sys.platform == 'win32':
        #XXX: hack to run pymake on windows
        if opts.make.endswith('.py'):
            cline = [sys.executable] + cline
        #XXX: hack so we can specialize the separator character on windows.
        # we really shouldn't need this, but y'know
        cline += ['__WIN32__=1']
        
    returncode = 0
    grepfor = None

    env = dict(os.environ)

    mdata = open(makefile)
    for line in mdata:
        m = tre.search(line)
        if m is None:
            break
        key, data = m.group(1, 2)
        data = eval(data)
        if key == 'commandline':
            cline.extend(data)
        elif key == 'returncode':
            returncode = data
        elif key == 'returncode-on':
            if sys.platform in data:
                returncode = data[sys.platform]
        elif key == 'environment':
            for k, v in data.iteritems():
                env[k] = v
        elif key == 'grep-for':
            grepfor = data
        else:
            print >>sys.stderr, "Unexpected #T key: %s" % key
            sys.exit(1)

    mdata.close()

    p = Popen(cline, stdout=PIPE, stderr=STDOUT, env=env)
    stdout, d = p.communicate()
    if p.returncode != returncode:
        print "FAIL (returncode=%i)" % p.returncode
        print stdout
    elif stdout.find('TEST-FAIL') != -1:
        print "FAIL"
        print stdout
    elif returncode == 0:
        if stdout.find(grepfor or 'TEST-PASS') != -1:
            print "PASS"
        else:
            print "FAIL (no expected output)"
            print stdout
    # check that test produced the expected output while failing
    elif grepfor:
        if stdout.find(grepfor) != -1:
            print "PASS"
        else:
            print "FAIL (no expected output)"
            print stdout
    else:
        print "EXPECTED-FAIL"

shutil.rmtree(opts.tempdir)