igt.py 5.99 KB
Newer Older
1
# coding=utf-8
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#
# Copyright (c) 2012 Intel Corporation
#
# 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:
#
# 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 AUTHOR(S) 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.

Dylan Baker's avatar
Dylan Baker committed
26 27 28 29 30 31 32 33 34 35
"""Integration for running intel-gpu-tools with the piglit framework.

To use this either configure piglit.conf's [igt] section, or set IGT_TEST_ROOT
to the root of a built igt directory.

This will stop if you are not running as root, or if there are other users of
drm. Even if you have rendernode support enabled.

"""

36 37 38 39
from __future__ import (
    absolute_import, division, print_function, unicode_literals
)

40 41 42 43
import os
import re
import subprocess

44
from framework import grouptools, exceptions, core, options
45
from framework import dmesg
46
from framework.profile import TestProfile, Test
47

48 49
__all__ = ['profile']

50

51
def check_environment():
Dylan Baker's avatar
Dylan Baker committed
52 53 54 55 56
    """Check that the environment that piglit is running in is appropriate.

    IGT requires root, debugfs to be mounted, and to be the only drm client.

    """
57 58
    debugfs_path = "/sys/kernel/debug/dri"
    if os.getuid() != 0:
59 60
        raise exceptions.PiglitInternalError(
            "Test Environment check: not root!")
61
    if not os.path.isdir(debugfs_path):
62 63
        raise exceptions.PiglitInternalError(
            "Test Environment check: debugfs not mounted properly!")
64
    for subdir in os.listdir(debugfs_path):
65 66
        if not os.path.isdir(os.path.join(debugfs_path, subdir)):
            continue
67 68 69
        clients = open(os.path.join(debugfs_path, subdir, "clients"), 'r')
        lines = clients.readlines()
        if len(lines) > 2:
70 71
            raise exceptions.PiglitInternalError(
                "Test Environment check: other drm clients running!")
72

73

74
if 'IGT_TEST_ROOT' in os.environ:
75
    IGT_TEST_ROOT = os.environ['IGT_TEST_ROOT']
76
else:
77
    IGT_TEST_ROOT = os.path.join(
78 79 80 81 82
        core.PIGLIT_CONFIG.required_get('igt', 'path'), 'tests')

if not os.path.exists(IGT_TEST_ROOT):
    raise exceptions.PiglitFatalError(
        'IGT directory does not exist. Missing: {}'.format(IGT_TEST_ROOT))
83

84
# check for the test lists
85 86 87 88 89 90
if os.path.exists(os.path.join(IGT_TEST_ROOT, 'test-list.txt')):
    TEST_LISTS = ['test-list.txt']
elif (os.path.exists(os.path.join(IGT_TEST_ROOT, 'single-tests.txt')) and
      os.path.exists(os.path.join(IGT_TEST_ROOT, 'multi-tests.txt'))):
    TEST_LISTS = ['single-tests.txt', 'multi-tests.txt']
else:
91
    raise exceptions.PiglitFatalError("intel-gpu-tools test lists not found.")
92

93

94
class IGTTestProfile(TestProfile):
Dylan Baker's avatar
Dylan Baker committed
95
    """Test profile for intel-gpu-tools tests."""
96 97

    def setup(self):
98
        if options.OPTIONS.execute:
99 100 101
            try:
                check_environment()
            except exceptions.PiglitInternalError as e:
102
                raise exceptions.PiglitFatalError(str(e))
103

Dylan Baker's avatar
Dylan Baker committed
104

105
profile = IGTTestProfile()  # pylint: disable=invalid-name
106

107

108
class IGTTest(Test):
Dylan Baker's avatar
Dylan Baker committed
109
    """Test class for running libdrm."""
110 111 112
    def __init__(self, binary, arguments=None):
        if arguments is None:
            arguments = []
113
        super(IGTTest, self).__init__(
114
            [os.path.join(IGT_TEST_ROOT, binary)] + arguments)
115
        self.timeout = 600
116

117
    def interpret_result(self):
118 119
        super(IGTTest, self).interpret_result()

120
        if self.result.returncode == 0:
121 122 123 124
            if not self.result.err:
                self.result.result = 'pass'
            else:
                self.result.result = 'warn'
125 126 127 128
        elif self.result.returncode == 77:
            self.result.result = 'skip'
        elif self.result.returncode == 78:
            self.result.result = 'timeout'
129 130
        elif self.result.returncode == 139:
            self.result.result = 'crash'
131
        else:
132
            self.result.result = 'fail'
Dylan Baker's avatar
Dylan Baker committed
133

134

135
def list_tests(listname):
Dylan Baker's avatar
Dylan Baker committed
136
    """Parse igt test list and return them as a list."""
137
    with open(os.path.join(IGT_TEST_ROOT, listname), 'r') as f:
138
        lines = (line.rstrip() for line in f.readlines())
139

140 141 142
    found_header = False

    for line in lines:
143
        if found_header:
144
            return line.split(" ")
145

146
        if "TESTLIST" in line:
147
            found_header = True
148

149
    return []
150

151

152
def add_subtest_cases(test):
Dylan Baker's avatar
Dylan Baker committed
153
    """Get subtest instances."""
154 155 156 157 158 159 160 161 162 163 164 165 166
    try:
        out = subprocess.check_output(
            [os.path.join(IGT_TEST_ROOT, test), '--list-subtests'],
            env=os.environ.copy(),
            universal_newlines=True)
    except subprocess.CalledProcessError as e:
        # a return code of 79 indicates there are no subtests
        if e.returncode == 79:
            profile.test_list[grouptools.join('igt', test)] = IGTTest(test)
        elif e.returncode != 0:
            print("Error: Could not list subtests for " + test)
        else:
            raise
167

168
        # If we reach here there are no subtests.
169
        return
170

171
    for subtest in (s for s in out.splitlines() if s):
Dylan Baker's avatar
Dylan Baker committed
172
        profile.test_list[grouptools.join('igt', test, subtest)] = \
173
            IGTTest(test, ['--run-subtest', subtest])
174

175

176
def populate_profile():
177 178 179
    tests = []
    for test_list in TEST_LISTS:
        tests.extend(list_tests(test_list))
180 181 182 183 184 185

    for test in tests:
        add_subtest_cases(test)


populate_profile()
186 187
profile.options['dmesg'] = dmesg.get_dmesg(True)
profile.options['dmesg'].regex = re.compile(r"(\[drm:|drm_|intel_|i915_)")