| Index: client/bin/factory.py
|
| diff --git a/client/bin/factory.py b/client/bin/factory.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e7f630c4a86a3ae36b7eae363ab18b39c474444d
|
| --- /dev/null
|
| +++ b/client/bin/factory.py
|
| @@ -0,0 +1,101 @@
|
| +# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +
|
| +# DESCRIPTION :
|
| +#
|
| +# This library provides common types and routines for the factory ui
|
| +# infrastructure. This library explicitly does not import gtk, to
|
| +# allow its use by the autotest control process.
|
| +
|
| +
|
| +import subprocess
|
| +import sys
|
| +import time
|
| +
|
| +
|
| +LOG_PATH = '/var/log/factory.log'
|
| +RESULT_FILE_PATH = '/var/run/factory_test_result'
|
| +
|
| +
|
| +def log(s):
|
| + print >> sys.stderr, 'FACTORY: ' + s
|
| +
|
| +
|
| +class TestData:
|
| + '''Factory-specific information on the tests to be run. The label
|
| + and trigger fields contain the description strings to be shown in
|
| + the test control list of the UI. The trigger field specifies the
|
| + keyboard shortcut to allow on-demain out-of-order test activation.
|
| + The dargs field allows test specific extra arguments.'''
|
| +
|
| + def __init__(self, label_en='', label_zw='', formal_name=None,
|
| + tag_prefix=None, trigger=None, automated_seq=[], dargs={}):
|
| + self.__dict__.update(vars())
|
| +
|
| + def __repr__(self):
|
| + d = ['%s=%s' % (l, repr(v))
|
| + for l, v in self.__dict__.items()
|
| + if l != 'self']
|
| + c = ('%s' % self.__class__).rpartition('.')[2]
|
| + return '%s(%s)' % (c, ','.join(d))
|
| +
|
| +
|
| +def test_map_index(formal_name, tag_prefix):
|
| + return formal_name + '.' + tag_prefix
|
| +
|
| +
|
| +def make_test_map(test_list):
|
| + return dict((test_map_index(test.formal_name, test.tag_prefix), test)
|
| + for test in test_list)
|
| +
|
| +
|
| +def make_trigger_set(test_list):
|
| + trigger_map = dict((test.trigger, test) for test in test_list)
|
| + delta = set(test_list) - set(trigger_map.values())
|
| + for test in delta:
|
| + collision = trigger_map[test.trigger]
|
| + log('ERROR: tests %s and %s both have trigger %s' %
|
| + (test.label_en, collision.label_en, test.trigger))
|
| + assert not delta
|
| + return set(trigger_map)
|
| +
|
| +
|
| +class UiClient:
|
| + '''Support communication with the factory_ui process. To simplify
|
| + surrounding code, this communication is an exchange of well formed
|
| + python expressions. Basically send wraps its arguments in a call
|
| + to repr() and recv calls eval() to re-generate the python data.'''
|
| +
|
| + def __init__(self, factory_ui_path):
|
| + self._proc = subprocess.Popen(factory_ui_path,
|
| + stdin=subprocess.PIPE,
|
| + stdout=subprocess.PIPE)
|
| +
|
| + def __del__(self):
|
| + log('control deleting factory_ui subprocess')
|
| + self._proc.terminate()
|
| + time.sleep(1)
|
| + if self._proc.poll() is None:
|
| + self._proc.kill()
|
| +
|
| + def send(self, x=None):
|
| + print >> self._proc.stdin, repr(x)
|
| + self._proc.stdin.flush()
|
| +
|
| + def send_cmd_next_test(self):
|
| + self.send(('next_test', None))
|
| +
|
| + def send_cmd_switch_to(self, trigger):
|
| + self.send(('switch_to', trigger))
|
| +
|
| + def recv(self):
|
| + return eval(self._proc.stdout.readline().rstrip())
|
| +
|
| + def recv_target_test_update(self, test_map):
|
| + update = self.recv()
|
| + log('control recv target test %s' % repr(update))
|
| + formal_name, tag_prefix, count = update
|
| + test = test_map.get(test_map_index(formal_name, tag_prefix), None)
|
| + return (test, count)
|
|
|