Zach Reizner | 52bb065 | 2016-09-15 15:07:54 -0700 | [diff] [blame] | 1 | # Copyright 2016 The Chromium OS Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
Gurchetan Singh | b114431 | 2017-02-22 14:31:26 -0800 | [diff] [blame] | 5 | import logging |
Gurchetan Singh | 193a0f0 | 2017-06-09 16:02:27 -0700 | [diff] [blame] | 6 | import os |
Gurchetan Singh | a1f606b | 2017-11-17 16:43:23 -0800 | [diff] [blame] | 7 | from autotest_lib.client.bin import utils |
Ilja H. Friedel | 2f7624c | 2016-11-08 16:28:40 -0800 | [diff] [blame] | 8 | from autotest_lib.client.common_lib import error |
Zach Reizner | 52bb065 | 2016-09-15 15:07:54 -0700 | [diff] [blame] | 9 | from autotest_lib.client.cros import service_stopper |
| 10 | from autotest_lib.client.cros.graphics import graphics_utils |
| 11 | |
| 12 | |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 13 | class DrmTest(object): |
Zach Reizner | 52bb065 | 2016-09-15 15:07:54 -0700 | [diff] [blame] | 14 | |
Chad Versace | 034373c | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 15 | def __init__(self, name, command=None, **kargs): |
| 16 | """ |
| 17 | @param name(str) |
| 18 | @param command(str): The shell command to run. If None, then reuse 'name'. |
| 19 | @param kargs: Test options |
| 20 | """ |
| 21 | |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 22 | self._opts = { |
| 23 | 'timeout': 20, |
Po-Hsien Wang | 04d7202 | 2017-04-25 11:55:06 -0700 | [diff] [blame] | 24 | 'display_required': True, |
| 25 | 'vulkan_required': False, |
| 26 | 'min_kernel_version': None |
| 27 | } |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 28 | self._opts.update(kargs) |
Chad Versace | 034373c | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 29 | self.name = name |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 30 | self._command = command |
Chad Versace | 034373c | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 31 | if self._command is None: |
| 32 | self._command = name |
Po-Hsien Wang | 04d7202 | 2017-04-25 11:55:06 -0700 | [diff] [blame] | 33 | |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 34 | def can_run(self): |
| 35 | """Indicate if the test can be run on the configuration.""" |
Gurchetan Singh | b114431 | 2017-02-22 14:31:26 -0800 | [diff] [blame] | 36 | num_displays = graphics_utils.get_num_outputs_on() |
Gurchetan Singh | b114431 | 2017-02-22 14:31:26 -0800 | [diff] [blame] | 37 | if num_displays == 0 and utils.get_device_type() == 'CHROMEBOOK': |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 38 | # Sanity check to guard against incorrect silent passes. |
| 39 | logging.error('Error: found Chromebook without display.') |
| 40 | return False |
| 41 | return True |
| 42 | |
| 43 | def should_run(self): |
| 44 | """Indicate if the test should be run on current configuration.""" |
| 45 | supported_apis = graphics_utils.GraphicsApiHelper().get_supported_apis() |
| 46 | num_displays = graphics_utils.get_num_outputs_on() |
Gurchetan Singh | 906a907 | 2017-11-17 15:32:03 -0800 | [diff] [blame] | 47 | gpu_type = utils.get_gpu_family() |
Gurchetan Singh | ee5c0c6 | 2017-11-17 15:52:38 -0800 | [diff] [blame] | 48 | soc = utils.get_cpu_soc_family() |
| 49 | kernel_version = os.uname()[2] |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 50 | if num_displays == 0 and self._opts['display_required']: |
Gurchetan Singh | b114431 | 2017-02-22 14:31:26 -0800 | [diff] [blame] | 51 | # If a test needs a display and we don't have a display, |
| 52 | # consider it a pass. |
| 53 | logging.warning('No display connected, skipping test.') |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 54 | return False |
| 55 | if self._opts['vulkan_required'] and 'vk' not in supported_apis: |
Po-Hsien Wang | 04d7202 | 2017-04-25 11:55:06 -0700 | [diff] [blame] | 56 | # If a test needs vulkan to run and we don't have it, |
| 57 | # consider it a pass |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 58 | logging.warning('Vulkan is required by test but is not ' |
| 59 | 'available on system. Skipping test.') |
| 60 | return False |
Gurchetan Singh | 193a0f0 | 2017-06-09 16:02:27 -0700 | [diff] [blame] | 61 | if self._opts['min_kernel_version']: |
Gurchetan Singh | 193a0f0 | 2017-06-09 16:02:27 -0700 | [diff] [blame] | 62 | min_kernel_version = self._opts['min_kernel_version'] |
| 63 | if utils.compare_versions(kernel_version, min_kernel_version) < 0: |
| 64 | logging.warning('Test requires kernel version >= %s,' |
| 65 | 'have version %s. Skipping test.' |
| 66 | % (min_kernel_version, kernel_version)) |
| 67 | return False |
Gurchetan Singh | 906a907 | 2017-11-17 15:32:03 -0800 | [diff] [blame] | 68 | if self.name == 'atomictest' and gpu_type == 'baytrail': |
| 69 | logging.warning('Baytrail is on kernel v4.4, but there is no ' |
| 70 | 'intention to enable atomic.') |
| 71 | return False |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 72 | return True |
Po-Hsien Wang | 04d7202 | 2017-04-25 11:55:06 -0700 | [diff] [blame] | 73 | |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 74 | def run(self): |
Ilja H. Friedel | 2f7624c | 2016-11-08 16:28:40 -0800 | [diff] [blame] | 75 | try: |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 76 | # TODO(pwang): consider TEE to another file if drmtests keep |
| 77 | # spewing so much output. |
Chad Versace | 018e174 | 2017-07-20 21:02:56 -0700 | [diff] [blame] | 78 | cmd_result = utils.run( |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 79 | self._command, |
| 80 | timeout=self._opts['timeout'], |
| 81 | stderr_is_expected=True, |
| 82 | verbose=True, |
| 83 | stdout_tee=utils.TEE_TO_LOGS, |
| 84 | stderr_tee=utils.TEE_TO_LOGS |
| 85 | ) |
Chad Versace | 018e174 | 2017-07-20 21:02:56 -0700 | [diff] [blame] | 86 | logging.info('Passed: %s', self._command) |
| 87 | logging.debug('Duration: %s: (%0.2fs)' |
| 88 | % (self._command, cmd_result.duration)) |
| 89 | return True |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 90 | except error.CmdTimeoutError as e: |
Chad Versace | f412ac4 | 2017-07-20 21:02:56 -0700 | [diff] [blame] | 91 | logging.error('Failed: Timeout while running %s (timeout=%0.2fs)' |
| 92 | % (self._command, self._opts['timeout'])) |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 93 | logging.debug(e) |
| 94 | return False |
| 95 | except error.CmdError as e: |
| 96 | logging.error('Failed: %s (exit=%d)' % (self._command, |
| 97 | e.result_obj.exit_status)) |
| 98 | logging.debug(e) |
| 99 | return False |
| 100 | except Exception as e: |
| 101 | logging.error('Failed: Unexpected exception while running %s' |
| 102 | % self._command) |
| 103 | logging.debug(e) |
| 104 | return False |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 105 | |
| 106 | drm_tests = { |
Chad Versace | 034373c | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 107 | test.name: test |
| 108 | for test in ( |
Gurchetan Singh | d0e571a | 2017-10-30 14:44:51 -0700 | [diff] [blame] | 109 | DrmTest('atomictest', 'atomictest -t all', min_kernel_version='4.4', |
| 110 | timeout=300), |
Chad Versace | 034373c | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 111 | DrmTest('drm_cursor_test'), |
Chad Versace | 034373c | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 112 | DrmTest('linear_bo_test'), |
Chad Versace | e9407f1 | 2017-07-20 21:02:58 -0700 | [diff] [blame] | 113 | DrmTest('mmap_test', timeout=300), |
Chad Versace | 034373c | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 114 | DrmTest('null_platform_test'), |
| 115 | DrmTest('swrast_test', display_required=False), |
Gurchetan Singh | 77365cc | 2018-04-02 09:18:58 -0700 | [diff] [blame^] | 116 | DrmTest('vgem_test'), |
Chad Versace | 034373c | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 117 | DrmTest('vk_glow', vulkan_required=True), |
| 118 | ) |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 119 | } |
| 120 | |
Po-Hsien Wang | a978869 | 2017-05-30 11:11:26 -0700 | [diff] [blame] | 121 | class graphics_Drm(graphics_utils.GraphicsTest): |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 122 | """Runs one, several or all of the drm-tests.""" |
| 123 | version = 1 |
| 124 | _services = None |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 125 | |
| 126 | def initialize(self): |
Po-Hsien Wang | a978869 | 2017-05-30 11:11:26 -0700 | [diff] [blame] | 127 | super(graphics_Drm, self).initialize() |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 128 | self._services = service_stopper.ServiceStopper(['ui']) |
| 129 | self._services.stop_services() |
| 130 | |
| 131 | def cleanup(self): |
| 132 | if self._services: |
| 133 | self._services.restore_services() |
Po-Hsien Wang | a978869 | 2017-05-30 11:11:26 -0700 | [diff] [blame] | 134 | super(graphics_Drm, self).cleanup() |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 135 | |
| 136 | # graphics_Drm runs all available tests if tests = None. |
Po-Hsien Wang | a978869 | 2017-05-30 11:11:26 -0700 | [diff] [blame] | 137 | def run_once(self, tests=None, perf_report=False): |
| 138 | self._test_failure_report_enable = perf_report |
Po-Hsien Wang | e83f6ea | 2017-12-08 18:58:19 -0800 | [diff] [blame] | 139 | self._test_failure_report_subtest = perf_report |
Chad Versace | daff3df | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 140 | for test in drm_tests.itervalues(): |
| 141 | if tests and test.name not in tests: |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 142 | continue |
| 143 | |
Chad Versace | daff3df | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 144 | logging.info('-----------------[%s]-----------------' % test.name) |
Po-Hsien Wang | e83f6ea | 2017-12-08 18:58:19 -0800 | [diff] [blame] | 145 | self.add_failures(test.name, subtest=test.name) |
| 146 | passed = False |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 147 | if test.should_run(): |
| 148 | if test.can_run(): |
Chad Versace | daff3df | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 149 | logging.debug('Running test %s.', test.name) |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 150 | passed = test.run() |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 151 | else: |
Po-Hsien Wang | e83f6ea | 2017-12-08 18:58:19 -0800 | [diff] [blame] | 152 | logging.info('Failed: test %s can not be run on current' |
| 153 | ' configurations.' % test.name) |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 154 | else: |
Po-Hsien Wang | e83f6ea | 2017-12-08 18:58:19 -0800 | [diff] [blame] | 155 | passed = True |
Chad Versace | daff3df | 2017-07-20 21:02:57 -0700 | [diff] [blame] | 156 | logging.info('Skipping test: %s.' % test.name) |
Po-Hsien Wang | b370886 | 2017-05-11 16:33:16 -0700 | [diff] [blame] | 157 | |
Po-Hsien Wang | e83f6ea | 2017-12-08 18:58:19 -0800 | [diff] [blame] | 158 | if passed: |
| 159 | self.remove_failures(test.name, subtest=test.name) |
| 160 | |
Po-Hsien Wang | a978869 | 2017-05-30 11:11:26 -0700 | [diff] [blame] | 161 | if self.get_failures(): |
| 162 | raise error.TestFail('Failed: %s' % self.get_failures()) |