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 library provides common types and routines for the factory ui |
| 9 # infrastructure. This library explicitly does not import gtk, to |
| 10 # allow its use by the autotest control process. |
| 11 |
| 12 |
| 13 import subprocess |
| 14 import sys |
| 15 import time |
| 16 |
| 17 |
| 18 LOG_PATH = '/var/log/factory.log' |
| 19 RESULT_FILE_PATH = '/var/run/factory_test_result' |
| 20 |
| 21 |
| 22 def log(s): |
| 23 print >> sys.stderr, 'FACTORY: ' + s |
| 24 |
| 25 |
| 26 class TestData: |
| 27 '''Factory-specific information on the tests to be run. The label |
| 28 and trigger fields contain the description strings to be shown in |
| 29 the test control list of the UI. The trigger field specifies the |
| 30 keyboard shortcut to allow on-demain out-of-order test activation. |
| 31 The dargs field allows test specific extra arguments.''' |
| 32 |
| 33 def __init__(self, label_en='', label_zw='', formal_name=None, |
| 34 tag_prefix=None, trigger=None, automated_seq=[], dargs={}): |
| 35 self.__dict__.update(vars()) |
| 36 |
| 37 def __repr__(self): |
| 38 d = ['%s=%s' % (l, repr(v)) |
| 39 for l, v in self.__dict__.items() |
| 40 if l != 'self'] |
| 41 c = ('%s' % self.__class__).rpartition('.')[2] |
| 42 return '%s(%s)' % (c, ','.join(d)) |
| 43 |
| 44 |
| 45 def test_map_index(formal_name, tag_prefix): |
| 46 return formal_name + '.' + tag_prefix |
| 47 |
| 48 |
| 49 def make_test_map(test_list): |
| 50 return dict((test_map_index(test.formal_name, test.tag_prefix), test) |
| 51 for test in test_list) |
| 52 |
| 53 |
| 54 def make_trigger_set(test_list): |
| 55 trigger_map = dict((test.trigger, test) for test in test_list) |
| 56 delta = set(test_list) - set(trigger_map.values()) |
| 57 for test in delta: |
| 58 collision = trigger_map[test.trigger] |
| 59 log('ERROR: tests %s and %s both have trigger %s' % |
| 60 (test.label_en, collision.label_en, test.trigger)) |
| 61 assert not delta |
| 62 return set(trigger_map) |
| 63 |
| 64 |
| 65 class UiClient: |
| 66 '''Support communication with the factory_ui process. To simplify |
| 67 surrounding code, this communication is an exchange of well formed |
| 68 python expressions. Basically send wraps its arguments in a call |
| 69 to repr() and recv calls eval() to re-generate the python data.''' |
| 70 |
| 71 def __init__(self, factory_ui_path): |
| 72 self._proc = subprocess.Popen(factory_ui_path, |
| 73 stdin=subprocess.PIPE, |
| 74 stdout=subprocess.PIPE) |
| 75 |
| 76 def __del__(self): |
| 77 log('control deleting factory_ui subprocess') |
| 78 self._proc.terminate() |
| 79 time.sleep(1) |
| 80 if self._proc.poll() is None: |
| 81 self._proc.kill() |
| 82 |
| 83 def send(self, x=None): |
| 84 print >> self._proc.stdin, repr(x) |
| 85 self._proc.stdin.flush() |
| 86 |
| 87 def send_cmd_next_test(self): |
| 88 self.send(('next_test', None)) |
| 89 |
| 90 def send_cmd_switch_to(self, trigger): |
| 91 self.send(('switch_to', trigger)) |
| 92 |
| 93 def recv(self): |
| 94 return eval(self._proc.stdout.readline().rstrip()) |
| 95 |
| 96 def recv_target_test_update(self, test_map): |
| 97 update = self.recv() |
| 98 log('control recv target test %s' % repr(update)) |
| 99 formal_name, tag_prefix, count = update |
| 100 test = test_map.get(test_map_index(formal_name, tag_prefix), None) |
| 101 return (test, count) |
OLD | NEW |