]> git.cworth.org Git - apitrace/commitdiff
Add helper script to use with git-bisect.
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 11 May 2011 13:56:36 +0000 (14:56 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Wed, 11 May 2011 13:59:52 +0000 (14:59 +0100)
scripts/README [new file with mode: 0644]
scripts/tracecheck.py [new file with mode: 0755]

diff --git a/scripts/README b/scripts/README
new file mode 100644 (file)
index 0000000..576e48f
--- /dev/null
@@ -0,0 +1,4 @@
+This directory contains several utilitarian scripts for common development
+tasks using apitrace tools.
+
+See their code for more details about their usage.
diff --git a/scripts/tracecheck.py b/scripts/tracecheck.py
new file mode 100755 (executable)
index 0000000..28b0720
--- /dev/null
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+##########################################################################
+#
+# Copyright 2011 VMware, Inc.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the 'Software'), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+##########################################################################/
+
+'''Check a trace replays successfully or not.
+
+It is meant to be used with git bisect.  See git bisect manpage for more
+details.
+'''
+
+
+import optparse
+import os.path
+import platform
+import re
+import subprocess
+import sys
+import traceback
+
+
+def good():
+    '''Tell git-bisect that this commit is good.'''
+
+    sys.stdout.write('GOOD\n')
+    sys.exit(0)
+
+
+def bad():
+    '''Tell git-bisect that this commit is bad.'''
+
+    sys.stdout.write('BAD\n')
+    sys.exit(1)
+
+
+def skip():
+    '''Tell git-bisect to skip this commit.'''
+
+    sys.stdout.write('SKIP\n')
+    sys.exit(125)
+
+
+def abort():
+    '''Tell git-bisect to abort.'''
+
+    sys.stdout.write('ABORT\n')
+    sys.exit(-1)
+
+
+def which(executable):
+    '''Search for the executable on the PATH.'''
+
+    if platform.system() == 'Windows':
+        exts = ['.exe']
+    else:
+        exts = ['']
+    dirs = os.environ['PATH'].split(os.path.pathsep)
+    for dir in dirs:
+        path = os.path.join(dir, executable)
+        for ext in exts:
+            if os.path.exists(path + ext):
+                return True
+    return False
+
+
+def main():
+    '''Main program.
+
+    It will always invoke sys.exit(), and never return normally.
+    '''
+
+    # Try to guess the build command.
+    if os.path.exists('SConstruct'):
+        default_build = 'scons'
+    elif os.path.exists('Makefile'):
+        default_build = 'make'
+    else:
+        default_build = None
+
+    # Parse command line options
+    optparser = optparse.OptionParser(
+        usage='\n\tgit bisect run %prog [options] -- [glretrace options] <trace>',
+        version='%%prog')
+    optparser.add_option(
+        '-b', '--build', metavar='COMMAND',
+        type='string', dest='build', default=default_build,
+        help='build command [default: %default]')
+    optparser.add_option(
+        '-r', '--retrace', metavar='PROGRAM',
+        type='string', dest='retrace', default='glretrace',
+        help='retrace command [default: %default]')
+    optparser.add_option(
+        '--gl-renderer', metavar='REGEXP',
+        type='string', dest='gl_renderer_re', default='^.*$',
+        help='require a matching GL_RENDERER string [default: %default]')
+
+    (options, args) = optparser.parse_args(sys.argv[1:])
+    if not args:
+        optparser.error("incorrect number of arguments")
+
+    # Build the source
+    if options.build:
+        sys.stdout.write(options.build + '\n')
+        sys.stdout.flush()
+        returncode = subprocess.call(options.build, shell=True)
+        if returncode:
+            skip()
+
+    # TODO: For this to be useful on Windows we'll also need an installation
+    # procedure here.
+
+    # Do some sanity checks.  In particular we want to make sure that the GL
+    # implementation is usable, and is the right one (i.e., we didn't fallback
+    # to a different OpenGL implementation due to missing symbols).
+    if platform.system() != 'Windows' and which('glxinfo'):
+        p = subprocess.Popen(['glxinfo'], stdout=subprocess.PIPE)
+        stdout, stderr = p.communicate()
+        if p.returncode:
+            skip()
+
+        # Search for the GL_RENDERER string
+        gl_renderer_header = 'OpenGL renderer string: '
+        gl_renderer = ''
+        for line in stdout.split('\n'):
+            if line.startswith(gl_renderer_header):
+                gl_renderer = line[len(gl_renderer_header):]
+
+        # and match it against the regular expression specified in the command
+        # line.
+        if not re.search(options.gl_renderer_re, gl_renderer):
+            sys.stderr.write("GL_RENDERER mismatch: %r !~ /%s/\n"  % (gl_renderer, options.gl_renderer_re))
+            skip()
+
+    # Run glretrace
+    retrace = [options.retrace] + args
+    sys.stdout.write(' '.join(retrace) + '\n')
+    sys.stdout.flush()
+    returncode = subprocess.call(retrace)
+    if returncode:
+        # TODO: allow other criterias here, such as, snapshot comparison or performance threshold
+        bad()
+
+    # Success
+    good()
+
+
+# Invoke main program, aborting the bisection on Ctrl+C or any uncaught Python
+# exception.
+if __name__ == '__main__':
+    try:
+        main()
+    except SystemExit:
+        raise
+    except KeyboardInterrupt:
+        abort()
+    except:
+        traceback.print_exc()
+        abort()