framework: fix run with valgrind option
[piglit.git] / framework / test / xorg.py
blobebc512c25fe3543242c77e4ca74a12a19e38d9eb
1 # encoding=utf-8
2 # Copyright (c) 2013-2014 Intel Corporation
3 # Copyright © 2013-2014, 2019 Intel Corporation
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
12 # This permission notice shall be included in all copies or substantial
13 # portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 """Test integration with Xorg suites.
24 This includes XTS and the rendercheck suite.
25 """
27 from __future__ import (
28 absolute_import, division, print_function, unicode_literals
30 import os
31 import re
32 import shutil
33 import subprocess
34 import tempfile
36 from .base import Test
39 class XTSTest(Test): # pylint: disable=too-few-public-methods
40 """ X Test Suite class
42 Runs a single test or subtest from XTS.
44 Arguments:
45 name -- the name of the test
46 testname -- the name of the test file
47 testnum -- the number of the test file
49 """
50 RESULTS_PATH = None
52 def __init__(self, command, testname, testdir, **kwargs):
53 super(XTSTest, self).__init__(command, **kwargs)
54 self.testname = testname
55 self.testdir = testdir
56 self.outdir = tempfile.mkdtemp()
57 self.result_file = os.path.join(self.outdir, testdir, testname)
58 self.env.update({"TET_RESFILE": self.result_file})
60 def _process_log_for_images(self, log):
61 """ Parse the image logfile """
62 images = []
63 search = re.compile('See file (Err[0-9]+.err)')
65 for line in log.splitlines():
66 match = search.search(line)
67 if match is not None:
68 # Can we parse any other useful information out to give a
69 # better description of each image?
70 desc = match.group(1)
72 # The error logs are text, with a header with width, height,
73 # and depth, then run-length-encoded pixel values (in
74 # hexadecimal). Use xtsttopng to convert the error log to a
75 # pair of PNGs so we can put them in the summary.
76 command = ['xtsttopng', os.path.join(self.result_file,
77 self.testdir,
78 match.group(1))]
79 try:
80 out = subprocess.check_output(command, cwd=self.cwd)
81 except OSError:
82 images.append({'image_desc': 'image processing failed',
83 'image_ref': None,
84 'image_render': None})
85 continue
87 # Each Err*.err log contains a rendered image, and a reference
88 # image that it was compared to. We relocate the to our tree
89 # with more useful names. (Otherwise, since tests generate
90 # error logs with numbers sequentially starting from 0, each
91 # subtest with an error would overwrite the previous test's
92 # images).
93 ref_path = os.path.join(
94 self.RESULTS_PATH, 'images', '{1}-{2}-ref.png'.format(
95 self.testname, match.group(1)))
96 render_path = os.path.join(
97 self.RESULTS_PATH, 'images', '{1}-{2}-render.png'.format(
98 self.testname, match.group(1)))
100 split = out.splitlines()
101 os.rename(os.path.join(self.cwd, split[0]), render_path)
102 os.rename(os.path.join(self.cwd, split[1]), ref_path)
104 images.append({'image_desc': desc,
105 'image_ref': ref_path,
106 'image_render': render_path})
108 return images
110 def interpret_result(self):
111 super(XTSTest, self).interpret_result()
113 try:
114 with open(self.result_file, 'r') as rfile:
115 log = rfile.read()
116 self.result.out = log
117 os.remove(self.result_file)
118 except IOError:
119 self.result.err = "No results file found"
120 log = ""
121 finally:
122 shutil.rmtree(self.outdir)
124 if self.result.returncode == 0:
125 if re.search('FAIL', self.result.out) is not None:
126 self.result.result = 'fail'
127 elif re.search('PASS', self.result.out) is not None:
128 self.result.result = 'pass'
129 else:
130 self.result.result = 'fail'
131 elif self.result.returncode == 77:
132 self.result.result = 'skip'
133 elif self.result.returncode == 1:
134 if re.search('Could not open all VSW5 fonts', log):
135 self.result.result = 'warn'
136 else:
137 self.result.result = 'fail'
139 self.result.images = self._process_log_for_images(log)
142 class RendercheckTest(Test):
144 def __init__(self, command, testname):
145 super(RendercheckTest, self).__init__(command)
146 self.testname = testname
148 def interpret_result(self):
149 super(RendercheckTest, self).interpret_result()
151 if self.result.returncode == 0:
152 self.result.result = 'pass'
153 elif self.result.returncode == 77:
154 self.result.result = 'skip'