OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2010 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 |
| 6 # DESCRIPTION : |
| 7 # |
| 8 # This is a factory test to test the external display (hdmi/vga/other) |
| 9 # UI based heavily on factory_Display/factory_Audio |
| 10 |
| 11 |
| 12 import gtk |
| 13 import logging |
| 14 import os |
| 15 import pango |
| 16 import sys |
| 17 |
| 18 from autotest_lib.client.bin import factory |
| 19 from autotest_lib.client.bin import factory_ui_lib as ful |
| 20 from autotest_lib.client.bin import test |
| 21 from autotest_lib.client.common_lib import error, utils |
| 22 |
| 23 |
| 24 _LABEL_STATUS_SIZE = (140, 30) |
| 25 _LABEL_START_STR = 'Connect headset.\n(Chinese)\n' + \ |
| 26 'Connect external display\n(Chinese)\n\nhit SPACE to start test.' |
| 27 _LABEL_RESPONSE_STR = ful.USER_PASS_FAIL_SELECT_STR + '\n' |
| 28 _VERBOSE = False |
| 29 |
| 30 _SUBTEST_LIST = [ |
| 31 ('External Display Video', |
| 32 {'msg' : 'Do you see video on External Display\n\n' + \ |
| 33 _LABEL_RESPONSE_STR, |
| 34 }), |
| 35 ] |
| 36 _OPTIONAL = ('External Display Audio', |
| 37 {'msg' : 'Do you hear audio from External Display\n\n' + \ |
| 38 _LABEL_RESPONSE_STR, |
| 39 'cfg':['amixer -c 0 cset name="IEC958 Playback Switch" on'], |
| 40 'cmd':'aplay -q', |
| 41 'postcfg':['amixer -c 0 cset name="IEC958 Playback Switch" off'], |
| 42 }) |
| 43 |
| 44 class factory_ExtDisplay(test.test): |
| 45 version = 1 |
| 46 |
| 47 def close_bgjob(self, name): |
| 48 job = self._job |
| 49 if job: |
| 50 utils.nuke_subprocess(job.sp) |
| 51 utils.join_bg_jobs([job], timeout=1) |
| 52 result = job.result |
| 53 if _VERBOSE and (result.stdout or result.stderr): |
| 54 raise error.CmdError( |
| 55 name, result, |
| 56 'stdout: %s\nstderr: %s' % (result.stdout, result.stderr)) |
| 57 self._job = None |
| 58 |
| 59 def goto_next_subtest(self): |
| 60 if not self._subtest_queue: |
| 61 gtk.main_quit() |
| 62 return |
| 63 self._current_subtest = self._subtest_queue.pop() |
| 64 name, cfg = self._current_subtest |
| 65 self._status_map[name] = ful.ACTIVE |
| 66 |
| 67 def start_subtest(self): |
| 68 subtest_name, subtest_cfg = self._current_subtest |
| 69 if 'cfg' in subtest_cfg: |
| 70 for cfg in subtest_cfg['cfg']: |
| 71 utils.system(cfg) |
| 72 factory.log("cmd: " + cfg) |
| 73 if 'cmd' in subtest_cfg: |
| 74 cmd = "%s %s" % (subtest_cfg['cmd'], self._sample) |
| 75 factory.log("cmd: " + cmd) |
| 76 self._job = utils.BgJob(cmd, stderr_level=logging.DEBUG) |
| 77 else: |
| 78 self._job = None |
| 79 |
| 80 def finish_subtest(self): |
| 81 subtest_name, subtest_cfg = self._current_subtest |
| 82 if 'postcfg' in subtest_cfg: |
| 83 for cfg in subtest_cfg['postcfg']: |
| 84 utils.system(cfg) |
| 85 factory.log("cmd: " + cfg) |
| 86 self.close_bgjob(subtest_cfg) |
| 87 |
| 88 def key_press_callback(self, widget, event): |
| 89 subtest_name, subtest_cfg = self._current_subtest |
| 90 if event.keyval == gtk.keysyms.space and not self._started: |
| 91 self._prompt_label.set_text(subtest_cfg['msg']) |
| 92 self._started = True |
| 93 self._test_widget.queue_draw() |
| 94 return True |
| 95 |
| 96 def key_release_callback(self, widget, event): |
| 97 if not self._started: |
| 98 return True |
| 99 subtest_name, subtest_cfg = self._current_subtest |
| 100 if event.keyval == gtk.keysyms.Tab and \ |
| 101 self._status_map[subtest_name] is ful.ACTIVE: |
| 102 self._status_map[subtest_name] = ful.FAILED |
| 103 self.finish_subtest() |
| 104 self.goto_next_subtest() |
| 105 elif event.keyval == gtk.keysyms.Return and \ |
| 106 self._status_map[subtest_name] is ful.ACTIVE: |
| 107 self._status_map[subtest_name] = ful.PASSED |
| 108 self.finish_subtest() |
| 109 self.goto_next_subtest() |
| 110 elif event.keyval == ord('Q'): |
| 111 gtk.main_quit() |
| 112 else: |
| 113 self._ft_state.exit_on_trigger(event) |
| 114 |
| 115 # evaluating a new subtest now |
| 116 if subtest_name is not self._current_subtest[0]: |
| 117 subtest_name, subtest_cfg = self._current_subtest |
| 118 self.start_subtest() |
| 119 self._prompt_label.set_text(subtest_cfg['msg']) |
| 120 |
| 121 self._test_widget.queue_draw() |
| 122 return True |
| 123 |
| 124 def label_status_expose(self, widget, event, name=None): |
| 125 status = self._status_map[name] |
| 126 widget.set_text(status) |
| 127 widget.modify_fg(gtk.STATE_NORMAL, ful.LABEL_COLORS[status]) |
| 128 |
| 129 def make_subtest_label_box(self, name): |
| 130 eb = gtk.EventBox() |
| 131 eb.modify_bg(gtk.STATE_NORMAL, ful.BLACK) |
| 132 label_status = ful.make_label(ful.UNTESTED, size=_LABEL_STATUS_SIZE, |
| 133 alignment=(0, 0.5), |
| 134 fg=ful.LABEL_COLORS[ful.UNTESTED]) |
| 135 expose_cb = lambda *x: self.label_status_expose(*x, **{'name':name}) |
| 136 label_status.connect('expose_event', expose_cb) |
| 137 label_en = ful.make_label(name, alignment=(1,0.5)) |
| 138 label_sep = ful.make_label(' : ', alignment=(0.5, 0.5)) |
| 139 hbox = gtk.HBox() |
| 140 hbox.pack_end(label_status, False, False) |
| 141 hbox.pack_end(label_sep, False, False) |
| 142 hbox.pack_end(label_en, False, False) |
| 143 eb.add(hbox) |
| 144 return eb |
| 145 |
| 146 def register_callbacks(self, window): |
| 147 window.connect('key-press-event', self.key_press_callback) |
| 148 window.add_events(gtk.gdk.KEY_PRESS_MASK) |
| 149 window.connect('key-release-event', self.key_release_callback) |
| 150 window.add_events(gtk.gdk.KEY_RELEASE_MASK) |
| 151 |
| 152 def locate_asample(self, sample): |
| 153 if not sample: |
| 154 raise error.TestFail('ERROR: Must provide an audio sample') |
| 155 if not os.path.isabs(sample): |
| 156 # assume its in deps |
| 157 sample = self.autodir + '/' + sample |
| 158 if not os.path.exists(sample): |
| 159 raise error.TestFail('ERROR: Unable to find audio sample %s' \ |
| 160 % sample) |
| 161 self._sample=sample |
| 162 |
| 163 def run_once(self, |
| 164 test_widget_size=None, |
| 165 trigger_set=None, |
| 166 has_audio=False, |
| 167 sample=None, |
| 168 ): |
| 169 |
| 170 factory.log('%s run_once' % self.__class__) |
| 171 # because audio files relative to that |
| 172 os.chdir(self.autodir) |
| 173 |
| 174 self._ft_state = ful.State(trigger_set=trigger_set) |
| 175 self._test_widget_size = test_widget_size |
| 176 self._started = False |
| 177 |
| 178 if has_audio: |
| 179 self.locate_asample(sample) |
| 180 _SUBTEST_LIST.append(_OPTIONAL) |
| 181 |
| 182 self._subtest_queue = [x for x in reversed(_SUBTEST_LIST)] |
| 183 self._status_map = dict((n, ful.UNTESTED) for n, c in _SUBTEST_LIST) |
| 184 |
| 185 |
| 186 prompt_label = ful.make_label(_LABEL_START_STR, fg=ful.WHITE) |
| 187 self._prompt_label = prompt_label |
| 188 |
| 189 vbox = gtk.VBox() |
| 190 vbox.pack_start(prompt_label, False, False) |
| 191 |
| 192 for name, cfg in _SUBTEST_LIST: |
| 193 label_box = self.make_subtest_label_box(name) |
| 194 vbox.pack_start(label_box, False, False) |
| 195 |
| 196 self._test_widget = vbox |
| 197 |
| 198 self.goto_next_subtest() |
| 199 self.start_subtest() |
| 200 |
| 201 self._ft_state.run_test_widget( |
| 202 test_widget=vbox, |
| 203 test_widget_size=test_widget_size, |
| 204 window_registration_callback=self.register_callbacks) |
| 205 |
| 206 failed_set = set(name for name, status in self._status_map.items() |
| 207 if status is not ful.PASSED) |
| 208 if failed_set: |
| 209 raise error.TestFail('some subtests failed (%s)' % |
| 210 ', '.join(failed_set)) |
| 211 |
| 212 factory.log('%s run_once finished' % self.__class__) |
OLD | NEW |