]> git.cworth.org Git - apitrace-tests/blobdiff - driver.py
Adjust for external bugs in reference state.
[apitrace-tests] / driver.py
index 1c4904cc24b335f3672e846386ac4fd707ce89ce..0a0dc5b7bd87f8cc0b98e807a98d29a8e84f7a70 100755 (executable)
--- a/driver.py
+++ b/driver.py
@@ -67,13 +67,24 @@ def pass_(reason=None):
 def popen(command, *args, **kwargs):
     if kwargs.get('cwd', None) is not None:
         sys.stdout.write('cd %s && ' % kwargs['cwd'])
-    if 'env' in kwargs:
-        for name, value in kwargs['env'].iteritems():
+
+    try:
+        env = kwargs.pop('env')
+    except KeyError:
+        env = None
+    else:
+        names = env.keys()
+        names.sort()
+        for name in names:
+            value = env[name]
             if value != os.environ.get(name, None):
                 sys.stdout.write('%s=%s ' % (name, value))
+            env[name] = str(value)
+
     sys.stdout.write(' '.join(command) + '\n')
     sys.stdout.flush()
-    return subprocess.Popen(command, *args, **kwargs)
+
+    return subprocess.Popen(command, *args, env=env, **kwargs)
 
 
 def _get_build_path(path):
@@ -232,7 +243,7 @@ class TestCase:
             return
 
         if self.trace_file is None:
-            name = os.path.basename(self.cmd[0])
+            name, ext = os.path.splitext(os.path.basename(self.cmd[0]))
             self.trace_file = os.path.abspath(os.path.join(self.results, name + '.trace'))
         if os.path.exists(self.trace_file):
             os.remove(self.trace_file)
@@ -250,7 +261,7 @@ class TestCase:
             wrapper = _get_build_path('wrappers/opengl32.dll')
             local_wrapper = os.path.join(os.path.dirname(self.cmd[0]), os.path.basename(wrapper))
             shutil.copy(wrapper, local_wrapper)
-            env['TRACE_FILE'] = self.trace_file
+            env['TRACE_FILE'] = str(self.trace_file)
         else:
             apitrace = _get_build_program('apitrace')
             cmd = [
@@ -305,7 +316,7 @@ class TestCase:
 
     def checkState(self, callNo, refStateFileName):
         srcState = self.getState(callNo)
-        refState = json.load(open(refStateFileName, 'rt'), strict=False)
+        refState = self.getRefState(refStateFileName)
 
         from jsondiff import Comparer, Differ
         comparer = Comparer(ignore_added = True)
@@ -321,6 +332,16 @@ class TestCase:
             differ.visit(refState, srcState)
             fail('state from call %u does not match %s' % (callNo, refStateFileName))
 
+    # Allo non-standard JS comments in JSON
+    json_comment_re = re.compile(r'//.*$', re.MULTILINE)
+
+    def getRefState(self, refStateFileName):
+        data = open(refStateFileName, 'rt').read()
+        data = self.json_comment_re.sub('', data)
+        state = json.loads(data, strict=False)
+        self.adjustRefState(state)
+        return state
+
     def getNamePrefix(self):
         name = os.path.basename(self.ref_dump)
         try:
@@ -343,17 +364,28 @@ class TestCase:
 
     def getImage(self, callNo):
         state = self.getState(callNo)
-        framebuffer = state['framebuffer']
         if self.doubleBuffer:
-            imageObj = framebuffer['GL_BACK']
+            attachments = ['GL_BACK', 'GL_BACK_LEFT', 'GL_BACK_RIGHT', 'GL_COLOR_ATTACHMENT0']
         else:
-            imageObj = framebuffer['GL_FRONT']
+            attachments = ['GL_FRONT', 'GL_FRONT_LEFT', 'GL_FRONT_RIGHT', 'GL_COLOR_ATTACHMENT0']
+        imageObj = self.getFramebufferAttachment(state, attachments)
         data = imageObj['__data__']
         stream = StringIO(base64.b64decode(data))
         im = Image.open(stream)
         im.save('test.png')
         return im
 
+    def getFramebufferAttachment(self, state, attachments):
+        framebufferObj = state['framebuffer']
+        for attachment in attachments:
+            try:
+                attachmentObj = framebufferObj[attachment]
+            except KeyError:
+                pass
+            else:
+                return attachmentObj
+        raise Exception("no attachment found")
+
     def getState(self, callNo):
         try:
             state = self.stateCache[callNo]
@@ -368,13 +400,66 @@ class TestCase:
         if p.returncode != 0:
             fail('retrace returned code %i' % (p.returncode))
 
+        self.adjustSrcState(state)
+
         self.stateCache[callNo] = state
 
         return state
 
+    def adjustSrcState(self, state):
+        # Do some adjustments on the obtained state to eliminate failures from
+        # bugs/issues outside of apitrace
+
+        try:
+            parameters = state['parameters']
+        except KeyError:
+            return
+
+        # On NVIDIA drivers glGetIntegerv(GL_INDEX_WRITEMASK) returns -1
+        self.replaceState(parameters, 'GL_INDEX_WRITEMASK', 255, -1)
+
+        # On Gallium 
+        if 'Gallium' in parameters['GL_RENDERER'].split():
+            # Gallium drivers have wrong defaults for draw/read buffer state
+            self.replaceState(parameters, 'GL_DRAW_BUFFER', 'GL_BACK_LEFT', 'GL_BACK')
+            self.replaceState(parameters, 'GL_DRAW_BUFFER0', 'GL_BACK_LEFT', 'GL_BACK')
+            self.replaceState(parameters, 'GL_READ_BUFFER', 'GL_BACK_LEFT', 'GL_BACK')
+            self.replaceState(parameters, 'GL_DRAW_BUFFER', 'GL_FRONT_LEFT', 'GL_FRONT')
+            self.replaceState(parameters, 'GL_DRAW_BUFFER0', 'GL_FRONT_LEFT', 'GL_FRONT')
+            self.replaceState(parameters, 'GL_READ_BUFFER', 'GL_FRONT_LEFT', 'GL_FRONT')
+
+    def adjustRefState(self, state):
+        # Do some adjustments on reference state to eliminate failures from
+        # bugs/issues outside of apitrace
+
+        try:
+            parameters = state['parameters']
+        except KeyError:
+            return
+
+        if platform.system() == 'Darwin' or True:
+            # Mac OS X drivers fail on GL_COLOR_SUM
+            # XXX: investigate this
+            self.removeState(parameters, 'GL_COLOR_SUM')
+
+    def replaceState(self, obj, key, srcValue, dstValue):
+        try:
+            value = obj[key]
+        except KeyError:
+            pass
+        else:
+            if value == srcValue:
+                obj[key] = dstValue
+
+    def removeState(self, obj, key):
+        try:
+            del obj[key]
+        except KeyError:
+            pass
+
     def _retrace(self, args = None, stdout=subprocess.PIPE):
         retrace = self.api_map[self.api] + 'retrace'
-        cmd = [_get_build_path(retrace)]
+        cmd = [_get_build_program(retrace)]
         if self.doubleBuffer:
             cmd += ['-db']
         else: