docs: Fix README link
[piglit.git] / tests / igt.py
blob261c09f0a527da823bf50336bca299643a0390a8
1 # coding=utf-8
3 # Copyright (c) 2012 Intel Corporation
5 # Permission is hereby granted, free of charge, to any person
6 # obtaining a copy of this software and associated documentation
7 # files (the "Software"), to deal in the Software without
8 # restriction, including without limitation the rights to use,
9 # copy, modify, merge, publish, distribute, sublicense, and/or
10 # sell copies of the Software, and to permit persons to whom the
11 # Software is furnished to do so, subject to the following
12 # conditions:
14 # This permission notice shall be included in all copies or
15 # substantial portions of the Software.
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
18 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
19 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
20 # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR(S) BE
21 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 # DEALINGS IN THE SOFTWARE.
26 """Integration for running intel-gpu-tools with the piglit framework.
28 To use this either configure piglit.conf's [igt] section, or set IGT_TEST_ROOT
29 to the root of a built igt directory.
31 This will stop if you are not running as root, or if there are other users of
32 drm. Even if you have rendernode support enabled.
34 """
36 import os
37 import re
38 import subprocess
40 from framework import grouptools, exceptions, core, options
41 from framework import dmesg
42 from framework.profile import TestProfile, Test
44 __all__ = ['profile']
47 def check_environment():
48 """Check that the environment that piglit is running in is appropriate.
50 IGT requires root, debugfs to be mounted, and to be the only drm client.
52 """
53 debugfs_path = "/sys/kernel/debug/dri"
54 if os.getuid() != 0:
55 raise exceptions.PiglitInternalError(
56 "Test Environment check: not root!")
57 if not os.path.isdir(debugfs_path):
58 raise exceptions.PiglitInternalError(
59 "Test Environment check: debugfs not mounted properly!")
60 for subdir in os.listdir(debugfs_path):
61 if not os.path.isdir(os.path.join(debugfs_path, subdir)):
62 continue
63 clients = open(os.path.join(debugfs_path, subdir, "clients"), 'r')
64 lines = clients.readlines()
65 if len(lines) > 2:
66 raise exceptions.PiglitInternalError(
67 "Test Environment check: other drm clients running!")
70 if 'IGT_TEST_ROOT' in os.environ:
71 IGT_TEST_ROOT = os.environ['IGT_TEST_ROOT']
72 else:
73 IGT_TEST_ROOT = os.path.join(
74 core.PIGLIT_CONFIG.required_get('igt', 'path'), 'tests')
76 if not os.path.exists(IGT_TEST_ROOT):
77 raise exceptions.PiglitFatalError(
78 'IGT directory does not exist. Missing: {}'.format(IGT_TEST_ROOT))
80 # check for the test lists
81 if os.path.exists(os.path.join(IGT_TEST_ROOT, 'test-list.txt')):
82 TEST_LISTS = ['test-list.txt']
83 elif (os.path.exists(os.path.join(IGT_TEST_ROOT, 'single-tests.txt')) and
84 os.path.exists(os.path.join(IGT_TEST_ROOT, 'multi-tests.txt'))):
85 TEST_LISTS = ['single-tests.txt', 'multi-tests.txt']
86 else:
87 raise exceptions.PiglitFatalError("intel-gpu-tools test lists not found.")
90 class IGTTestProfile(TestProfile):
91 """Test profile for intel-gpu-tools tests."""
93 def setup(self):
94 if options.OPTIONS.execute:
95 try:
96 check_environment()
97 except exceptions.PiglitInternalError as e:
98 raise exceptions.PiglitFatalError(str(e))
101 profile = IGTTestProfile() # pylint: disable=invalid-name
104 class IGTTest(Test):
105 """Test class for running libdrm."""
106 def __init__(self, binary, arguments=None):
107 if arguments is None:
108 arguments = []
109 super(IGTTest, self).__init__(
110 [os.path.join(IGT_TEST_ROOT, binary)] + arguments)
111 self.timeout = 600
113 def interpret_result(self):
114 super(IGTTest, self).interpret_result()
116 if self.result.returncode == 0:
117 if not self.result.err:
118 self.result.result = 'pass'
119 else:
120 self.result.result = 'warn'
121 elif self.result.returncode == 77:
122 self.result.result = 'skip'
123 elif self.result.returncode == 78:
124 self.result.result = 'timeout'
125 elif self.result.returncode == 139:
126 self.result.result = 'crash'
127 else:
128 self.result.result = 'fail'
131 def list_tests(listname):
132 """Parse igt test list and return them as a list."""
133 with open(os.path.join(IGT_TEST_ROOT, listname), 'r') as f:
134 lines = (line.rstrip() for line in f.readlines())
136 found_header = False
138 for line in lines:
139 if found_header:
140 return line.split(" ")
142 if "TESTLIST" in line:
143 found_header = True
145 return []
148 def add_subtest_cases(test):
149 """Get subtest instances."""
150 try:
151 out = subprocess.check_output(
152 [os.path.join(IGT_TEST_ROOT, test), '--list-subtests'],
153 env=os.environ.copy(),
154 universal_newlines=True)
155 except subprocess.CalledProcessError as e:
156 # a return code of 79 indicates there are no subtests
157 if e.returncode == 79:
158 profile.test_list[grouptools.join('igt', test)] = IGTTest(test)
159 elif e.returncode != 0:
160 print("Error: Could not list subtests for " + test)
161 else:
162 raise
164 # If we reach here there are no subtests.
165 return
167 for subtest in (s for s in out.splitlines() if s):
168 profile.test_list[grouptools.join('igt', test, subtest)] = \
169 IGTTest(test, ['--run-subtest', subtest])
172 def populate_profile():
173 tests = []
174 for test_list in TEST_LISTS:
175 tests.extend(list_tests(test_list))
177 for test in tests:
178 add_subtest_cases(test)
181 populate_profile()
182 profile.options['dmesg'] = dmesg.get_dmesg(True)
183 profile.options['dmesg'].regex = re.compile(r"(\[drm:|drm_|intel_|i915_)")