• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2012 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#
5# GLMark outputs a final performance score, and it checks the performance score
6# against minimum requirement if min_score is set.
7
8import logging
9import os
10import re
11import string
12
13from autotest_lib.client.bin import test, utils
14from autotest_lib.client.common_lib import error
15from autotest_lib.client.cros import service_stopper
16from autotest_lib.client.cros.graphics import graphics_utils
17
18GLMARK2_TEST_RE = (
19    r'^\[(?P<scene>.*)\] (?P<options>.*): FPS: (?P<fps>\d+) FrameTime: '
20    r'(?P<frametime>\d+.\d+) ms$')
21GLMARK2_SCORE_RE = r'glmark2 Score: (\d+)'
22
23# perf value description strings may only contain letters, numbers, periods,
24# dashes and underscores.
25# But glmark2 test names are usually in the form:
26#   scene-name:opt=val:opt=v1,v2;v3,v4 or scene:<default>
27# which we convert to:
28#   scene-name.opt_val.opt_v1-v2_v3-v4 or scene.default
29description_table = string.maketrans(':,=;', '.-__')
30description_delete = '<>'
31
32
33class graphics_GLMark2(test.test):
34    """Runs glmark2, which benchmarks only calls compatible with OpenGL ES 2.0"""
35    version = 1
36    preserve_srcdir = True
37    _services = None
38    GSC = None
39
40    def setup(self):
41        self.job.setup_dep(['glmark2'])
42
43    def initialize(self):
44        self.GSC = graphics_utils.GraphicsStateChecker()
45        # If UI is running, we must stop it and restore later.
46        self._services = service_stopper.ServiceStopper(['ui'])
47        self._services.stop_services()
48
49    def cleanup(self):
50        if self._services:
51            self._services.restore_services()
52        if self.GSC:
53            keyvals = self.GSC.get_memory_keyvals()
54            for key, val in keyvals.iteritems():
55                self.output_perf_value(
56                    description=key,
57                    value=val,
58                    units='bytes',
59                    higher_is_better=False)
60            self.GSC.finalize()
61            self.write_perf_keyval(keyvals)
62
63    def run_once(self, size='800x600', hasty=False, min_score=None):
64        dep = 'glmark2'
65        dep_dir = os.path.join(self.autodir, 'deps', dep)
66        self.job.install_pkg(dep, 'dep', dep_dir)
67
68        glmark2 = os.path.join(self.autodir, 'deps/glmark2/glmark2')
69        if not os.path.exists(glmark2):
70            raise error.TestFail('Failed: Could not find test binary.')
71
72        glmark2_data = os.path.join(self.autodir, 'deps/glmark2/data')
73
74        options = []
75        options.append('--data-path %s' % glmark2_data)
76        options.append('--size %s' % size)
77        options.append('--annotate')
78        if hasty:
79            options.append('-b :duration=0.2')
80        else:
81            options.append('-b :duration=2')
82        cmd = glmark2 + ' ' + ' '.join(options)
83
84        if os.environ.get('CROS_FACTORY'):
85            from autotest_lib.client.cros import factory_setup_modules
86            from cros.factory.test import ui
87            ui.start_reposition_thread('^glmark')
88
89        # TODO(ihf): Switch this test to use perf.PerfControl like
90        #            graphics_GLBench once it is stable. crbug.com/344766.
91        if not hasty:
92            if not utils.wait_for_idle_cpu(60.0, 0.1):
93                if not utils.wait_for_idle_cpu(20.0, 0.2):
94                    raise error.TestFail('Failed: Could not get idle CPU.')
95            if not utils.wait_for_cool_machine():
96                raise error.TestFail('Failed: Could not get cold machine.')
97
98        # In this test we are manually handling stderr, so expected=True.
99        # Strangely autotest takes CmdError/CmdTimeoutError as warning only.
100        try:
101            result = utils.run(cmd,
102                               stderr_is_expected=True,
103                               stdout_tee=utils.TEE_TO_LOGS,
104                               stderr_tee=utils.TEE_TO_LOGS)
105        except error.CmdError:
106            raise error.TestFail('Failed: CmdError running %s' % cmd)
107        except error.CmdTimeoutError:
108            raise error.TestFail('Failed: CmdTimeout running %s' % cmd)
109
110        logging.info(result)
111        for line in result.stderr.splitlines():
112            if line.startswith('Error:'):
113                # Line already starts with 'Error: ", not need to prepend.
114                raise error.TestFail(line)
115
116        # Numbers in hasty mode are not as reliable, so don't send them to
117        # the dashboard etc.
118        if not hasty:
119            keyvals = {}
120            score = None
121            test_re = re.compile(GLMARK2_TEST_RE)
122            for line in result.stdout.splitlines():
123                match = test_re.match(line)
124                if match:
125                    test = '%s.%s' % (match.group('scene'),
126                                      match.group('options'))
127                    test = test.translate(description_table, description_delete)
128                    frame_time = match.group('frametime')
129                    keyvals[test] = frame_time
130                    self.output_perf_value(
131                        description=test,
132                        value=frame_time,
133                        units='ms',
134                        higher_is_better=False)
135                else:
136                    # glmark2 output the final performance score as:
137                    #  glmark2 Score: 530
138                    match = re.findall(GLMARK2_SCORE_RE, line)
139                    if match:
140                        score = int(match[0])
141            if score is None:
142                raise error.TestFail('Failed: Unable to read benchmark score')
143            # Output numbers for plotting by harness.
144            logging.info('GLMark2 score: %d', score)
145            if os.environ.get('CROS_FACTORY'):
146                from autotest_lib.client.cros import factory_setup_modules
147                from cros.factory.event_log import EventLog
148                EventLog('graphics_GLMark2').Log('glmark2_score', score=score)
149            keyvals['glmark2_score'] = score
150            self.write_perf_keyval(keyvals)
151            self.output_perf_value(
152                description='Score',
153                value=score,
154                units='score',
155                higher_is_better=True)
156
157            if min_score is not None and score < min_score:
158                raise error.TestFail(
159                    'Failed: Benchmark score %d < %d (minimum score '
160                    'requirement)' % (score, min_score))
161