diff --git a/mod_for_factory_scripts/200patchInitScript b/mod_for_factory_scripts/200patchInitScript index 391ff07a7d..d0cdd9cbfa 100755 --- a/mod_for_factory_scripts/200patchInitScript +++ b/mod_for_factory_scripts/200patchInitScript @@ -49,11 +49,11 @@ stop on starting halt or starting reboot script cd /usr/local/autotest -eval \$(./factory_startx.sh) +eval \$(./deps/factory/startx.sh) date >> /var/log/factory.log if [ ! -e factory_started ]; then touch factory_started - cp -f site_tests/suite_Factory/control.ui control + cp -f site_tests/suite_Factory/control . ./bin/autotest control >> /var/log/factory.log 2>&1 else ./tools/autotest >> /var/log/factory.log 2>&1 diff --git a/mod_for_factory_scripts/400configAutotest b/mod_for_factory_scripts/400configAutotest index a848c97454..f642e38729 100755 --- a/mod_for_factory_scripts/400configAutotest +++ b/mod_for_factory_scripts/400configAutotest @@ -6,14 +6,6 @@ echo "Configure autotest setting." -SCRIPT_DIR="${GCLIENT_ROOT}/src/scripts/mod_for_factory_scripts/" -AUTOTEST_DIR="${ROOT_FS_DIR}/usr/local/autotest/" - -cp "${SCRIPT_DIR}/factory_ui" "${AUTOTEST_DIR}" -chmod +x "${AUTOTEST_DIR}/factory_ui" -cp "${SCRIPT_DIR}/factory_startx.sh" "${AUTOTEST_DIR}" -chmod +x "${AUTOTEST_DIR}/factory_startx.sh" - GLOBAL_CONFIG="${ROOT_FS_DIR}/usr/local/autotest/global_config.ini" if [ -f "${GLOBAL_CONFIG}" ]; then diff --git a/mod_for_factory_scripts/factory_startx.sh b/mod_for_factory_scripts/factory_startx.sh deleted file mode 100644 index 5a38fa3252..0000000000 --- a/mod_for_factory_scripts/factory_startx.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -# 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. - -XAUTH=/usr/bin/xauth -XAUTH_FILE="/var/run/factory_ui.auth" -SERVER_READY= -DISPLAY=":0" - -user1_handler () { - echo "X server ready..." 1>&2 - SERVER_READY=y -} - -trap user1_handler USR1 -MCOOKIE=$(head -c 8 /dev/urandom | openssl md5) -${XAUTH} -q -f ${XAUTH_FILE} add ${DISPLAY} . ${MCOOKIE} - -/sbin/xstart.sh ${XAUTH_FILE} & - -while [ -z ${SERVER_READY} ]; do - sleep .1 -done - -/sbin/initctl emit factory-ui-started -cat /proc/uptime > /tmp/uptime-x-started - -echo "DISPLAY=${DISPLAY}; export DISPLAY" -echo "XAUTHORITY=${XAUTH_FILE}; export XAUTHORITY" diff --git a/mod_for_factory_scripts/factory_ui b/mod_for_factory_scripts/factory_ui deleted file mode 100644 index 35b8d72d6d..0000000000 --- a/mod_for_factory_scripts/factory_ui +++ /dev/null @@ -1,431 +0,0 @@ -#!/usr/bin/python -# -# 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 UI is intended to be used by the factory autotest suite to -# provide factory operators feedback on test status and control over -# execution order. -# -# In short, the UI is composed of a 'console' panel on the bottom of -# the screen which displays the autotest log, and there is also a -# 'test list' panel on the right hand side of the screen. The -# majority of the screen is dedicated to tests, which are executed in -# seperate processes, but instructed to display their own UIs in this -# dedicated area whenever possible. Tests in the test list are -# executed in order by default, but can be activated on demand via -# associated keyboard shortcuts (triggers). As tests are run, their -# status is color-indicated to the operator -- greyed out means -# untested, yellow means active, green passed and red failed. - - -import gobject -import gtk -import os -import pango -import subprocess -import sys -import time - - -def XXX_log(s): - print >> sys.stderr, '--- XXX : ' + s - -_ACTIVE = 'ACTIVE' -_PASSED = 'PASS' -_FAILED = 'FAIL' -_UNTESTED = 'UNTESTED' - -_LABEL_COLORS = { - _ACTIVE: gtk.gdk.color_parse('light goldenrod'), - _PASSED: gtk.gdk.color_parse('pale green'), - _FAILED: gtk.gdk.color_parse('tomato'), - _UNTESTED: gtk.gdk.color_parse('dark slate grey')} - -_LABEL_EN_SIZE = (160, 35) -_LABEL_EN_FONT = pango.FontDescription('courier new extra-condensed 16') -_LABEL_ZW_SIZE = (70, 35) -_LABEL_ZW_FONT = pango.FontDescription('normal 12') -_LABEL_T_SIZE = (30, 35) -_LABEL_T_FONT = pango.FontDescription('courier new italic ultra-condensed 10') -_LABEL_UNTESTED_FG = gtk.gdk.color_parse('grey40') -_LABEL_TROUGH_COLOR = gtk.gdk.color_parse('grey20') -_LABEL_STATUS_SIZE = (140, 30) -_LABEL_STATUS_FONT = pango.FontDescription( - 'courier new bold extra-condensed 16') -_SEP_COLOR = gtk.gdk.color_parse('grey50') -_BLACK = gtk.gdk.color_parse('black') -_LIGHT_GREEN = gtk.gdk.color_parse('light green') -_OTHER_LABEL_FONT = pango.FontDescription('courier new condensed 20') - -class console_proc: - '''Display a progress log. Implemented by launching an borderless - xterm at a strategic location, and running tail against the log.''' - - def __init__(self, allocation, log_file_path): - xterm_coords = '135x14+%d+%d' % (allocation.x, allocation.y) - XXX_log('xterm_coords = %s' % xterm_coords) - xterm_cmd = ('xterm --geometry %s -bw 0 -e ' % xterm_coords + - 'tail -f %s' % log_file_path) - self._proc = subprocess.Popen(xterm_cmd.split()) - - def __del__(self): - XXX_log('console_proc __del__') - self._proc.kill() - - -# Routines to communicate with the autotest control file, using python -# expressions. The stdin_callback assures notification for any new -# messages. - -def stdin_callback(s, c): - XXX_log('stdin_callback, quitting gtk main') - gtk.main_quit() - return True - -def control_recv(): - return eval(sys.stdin.readline().rstrip()) - -def control_send(x): - print repr(x) - sys.stdout.flush() - -def control_send_target_test_update(test): - XXX_log('ui send_target_test_update %s.%s_%s' % - (test.formal_name, test.tag_prefix, test.count)) - control_send((test.formal_name, test.tag_prefix, test.count)) - - -# Capture keyboard events here for debugging -- under normal -# circumstances, all keyboard events should be captured by executing -# tests, and hence this should not be called. - -def handle_key_release_event(_, event): - XXX_log('base ui key event (%s)' % event.keyval) - return True - - -class test_label_box(gtk.EventBox): - - def __init__(self, test): - gtk.EventBox.__init__(self) - label_en = gtk.Label(test.label_en) - label_en.set_size_request(*_LABEL_EN_SIZE) - label_en.modify_font(_LABEL_EN_FONT) - label_en.set_alignment(0.8, 0.5) - label_en.modify_fg(gtk.STATE_NORMAL, _LABEL_UNTESTED_FG) - label_zw = gtk.Label(test.label_zw) - label_zw.set_size_request(*_LABEL_ZW_SIZE) - label_zw.modify_font(_LABEL_ZW_FONT) - label_zw.set_alignment(0.2, 0.5) - label_zw.modify_fg(gtk.STATE_NORMAL, _LABEL_UNTESTED_FG) - label_t = gtk.Label('C-' + test.trigger) - label_t.set_size_request(*_LABEL_T_SIZE) - label_t.modify_font(_LABEL_T_FONT) - label_t.set_alignment(0.5, 0.5) - label_t.modify_fg(gtk.STATE_NORMAL, _BLACK) - hbox = gtk.HBox() - hbox.pack_start(label_en, False, False) - hbox.pack_start(label_zw, False, False) - hbox.pack_start(label_t, False, False) - self.add(hbox) - self.label_list = [label_en, label_zw] - - def update_status(self, status): - if status != _UNTESTED: - self.modify_fg(gtk.STATE_NORMAL, _BLACK) - for label in self.label_list: - label.modify_fg(gtk.STATE_NORMAL, _BLACK) - self.modify_bg(gtk.STATE_NORMAL, _LABEL_COLORS[status]) - self.queue_draw() - - -class subtest_label_box(gtk.EventBox): - - def __init__(self, test): - gtk.EventBox.__init__(self) - self.modify_bg(gtk.STATE_NORMAL, _BLACK) - label_status = gtk.Label(_UNTESTED) - label_status.set_size_request(*_LABEL_STATUS_SIZE) - label_status.set_alignment(0, 0.5) - label_status.modify_font(_LABEL_STATUS_FONT) - label_status.modify_fg(gtk.STATE_NORMAL, _LABEL_UNTESTED_FG) - label_en = gtk.Label(test.label_en) - label_en.set_alignment(1, 0.5) - label_en.modify_font(_LABEL_EN_FONT) - label_en.modify_fg(gtk.STATE_NORMAL, _LIGHT_GREEN) - label_zw = gtk.Label(test.label_zw) - label_zw.set_alignment(1, 0.5) - label_zw.modify_font(_LABEL_ZW_FONT) - label_zw.modify_fg(gtk.STATE_NORMAL, _LIGHT_GREEN) - label_sep = gtk.Label(' : ') - label_sep.set_alignment(0.5, 0.5) - label_sep.modify_font(_LABEL_EN_FONT) - label_sep.modify_fg(gtk.STATE_NORMAL, _LIGHT_GREEN) - hbox = gtk.HBox() - hbox.pack_end(label_status, False, False) - hbox.pack_end(label_sep, False, False) - hbox.pack_end(label_zw, False, False) - hbox.pack_end(label_en, False, False) - self.add(hbox) - self.label_status = label_status - - def update_status(self, status): - if status != _UNTESTED: - self.label_status.set_text(status) - self.label_status.modify_fg(gtk.STATE_NORMAL, _LABEL_COLORS[status]) - self.queue_draw() - - -class status_map(): - - def __init__(self): - self.status_dict = {} - - def index(self, formal_name, tag_prefix): - return '%s.%s' % (formal_name, tag_prefix) - - def lookup(self, formal_name, tag_prefix): - return self.status_dict.setdefault( - self.index(formal_name, tag_prefix), - (_UNTESTED, 0)) - - def update(self, formal_name, tag_prefix, status, count): - _, existing_count = self.lookup(formal_name, tag_prefix) - if count > existing_count: - index = self.index(formal_name, tag_prefix) - self.status_dict[index] = (status, count) - - def get_subtest_status(self, test): - map(self.set_test_status, test.automated_seq) - sub_status_set = set(st.status for st in test.automated_seq) - min_count = min([st.count for st in test.automated_seq]) - max_count = max([st.count for st in test.automated_seq]) - if len(sub_status_set) == 1: - return (sub_status_set.pop(), max_count) - if test.count > min_count: - return (_ACTIVE, max_count) - return (_FAILED, max_count) - - def set_test_status(self, test): - status, count = ( - test.automated_seq - and self.get_subtest_status(test) - or self.lookup(test.formal_name, test.tag_prefix)) - status = test.count > count and _ACTIVE or status - max_count = max(test.count, count) - if test.status != status or test.count != max_count: - XXX_log('status change for %s : %s/%s -> %s/%s' % - (self.index(test.formal_name, test.tag_prefix), - test.count, test.status, max_count, status)) - test.status = status - test.count = max_count - test.label_box.update_status(status) - - -def refresh_test_status(status_file_path, test_list): - smap = status_map() - with open(status_file_path) as file: - for line in file: - columns = line.split('\t') - if len(columns) >= 8 and not columns[0] and not columns[1]: - status = columns[2] == 'GOOD' and _PASSED or _FAILED - formal_name, _, tag = columns[3].rpartition('.') - tag_prefix, _, count = tag.rpartition('_') - count = int(count) - smap.update(formal_name, tag_prefix, status, count) - map(smap.set_test_status, test_list) - - -def set_active_test(test): - test.count += 1 - test.label_box.update_status(_ACTIVE) - control_send_target_test_update(test) - - -def make_hsep(width=1): - frame = gtk.EventBox() - frame.set_size_request(-1, width) - frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR) - return frame - - -def make_vsep(width=1): - frame = gtk.EventBox() - frame.set_size_request(width, -1) - frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR) - return frame - - -def make_notest_label(): - label = gtk.Label('no active test') - label.modify_font(_OTHER_LABEL_FONT) - label.set_alignment(0.5, 0.5) - label.modify_fg(gtk.STATE_NORMAL, _LIGHT_GREEN) - box = gtk.EventBox() - box.modify_bg(gtk.STATE_NORMAL, _BLACK) - box.add(label) - return box - - -def make_automated_seq_widget(as_test): - vbox = gtk.VBox() - vbox.set_spacing(0) - map(lambda st: vbox.pack_start(st.label_box, False, False), - as_test.automated_seq) - return vbox - - -def main(): - window = gtk.Window(gtk.WINDOW_TOPLEVEL) - window.connect('destroy', lambda _: gtk.main_quit()) - window.modify_bg(gtk.STATE_NORMAL, _BLACK) - - screen = window.get_screen() - screen_size = (screen.get_width(), screen.get_height()) - window.set_size_request(*screen_size) - - label_trough = gtk.VBox() - label_trough.set_spacing(0) - - rhs_box = gtk.EventBox() - rhs_box.modify_bg(gtk.STATE_NORMAL, _LABEL_TROUGH_COLOR) - rhs_box.add(label_trough) - - console_box = gtk.EventBox() - console_box.set_size_request(-1, 180) - console_box.modify_bg(gtk.STATE_NORMAL, _BLACK) - - notest_label = make_notest_label() - - test_widget_box = gtk.Alignment(xalign=0.5, yalign=0.5) - test_widget_box.set_size_request(-1, -1) - test_widget_box.add(notest_label) - - lhs_box = gtk.VBox() - lhs_box.pack_end(console_box, False, False) - lhs_box.pack_start(test_widget_box) - lhs_box.pack_start(make_hsep(3), False, False) - - base_box = gtk.HBox() - base_box.pack_end(rhs_box, False, False) - base_box.pack_end(make_vsep(3), False, False) - base_box.pack_start(lhs_box) - - window.connect('key-release-event', handle_key_release_event) - window.add_events(gtk.gdk.KEY_RELEASE_MASK) - - # On startup, get general configuration data from the autotest - # control program, specifically the list of tests to run (in - # order) and some filenames. - XXX_log('pulling control info') - test_list = control_recv() - status_file_path = control_recv() - log_file_path = control_recv() - - for test in test_list: - test.status = None - test.count = 0 - test.tag_prefix = test.trigger - test.label_box = test_label_box(test) - for subtest in test.automated_seq: - subtest.status = None - subtest.count = 0 - subtest.tag_prefix = test.formal_name - subtest.label_box = subtest_label_box(subtest) - label_trough.pack_start(test.label_box, False, False) - label_trough.pack_start(make_hsep(), False, False) - - window.add(base_box) - window.show_all() - - test_widget_allocation = test_widget_box.get_allocation() - test_widget_size = (test_widget_allocation.width, - test_widget_allocation.height) - XXX_log('test_widget_size = %s' % repr(test_widget_size)) - control_send(test_widget_size) - - trigger_dict = dict((test.trigger, test) for test in test_list) - - refresh_test_status(status_file_path, test_list) - remaining_tests_queue = [x for x in reversed(test_list) - if x.status == _UNTESTED] - XXX_log('remaining_tests_queue = %s' % - repr([x.label_en for x in remaining_tests_queue])) - - active_test = None - - gobject.io_add_watch(sys.stdin, gobject.IO_IN, stdin_callback) - - console = console_proc(console_box.get_allocation(), log_file_path) - - XXX_log('finished ui setup') - - # Test selection is driven either by triggers or by the - # remaining_tests_queue. If a trigger was seen, explicitly run - # the corresponding test. Otherwise choose the next test from the - # queue. Tests are removed from the queue as they are run, - # regarless of the outcome. Tests that are interrupted by trigger - # are treated as having failed. - # - # Iterations in the main loop here are driven by data availability - # on stdin, which is used to communicate with the autotest control - # program. On each step through the loop, a trigger is received - # (possibly None) to indicate how the next test should be selected. - - while remaining_tests_queue: - command, arg = control_recv() - XXX_log('ui received command %s(%s)' % (command, arg)) - if command == 'switch_to': - active_test = trigger_dict.get(arg, None) - if active_test in remaining_tests_queue: - remaining_tests_queue.remove(active_test) - set_active_test(active_test) - elif command == 'next_test': - active_test = remaining_tests_queue.pop() - set_active_test(active_test) - else: - XXX_log('ui command unknown, exiting...') - break - if active_test.automated_seq: - XXX_log('ui starting automated_seq') - subtest_queue = [x for x in reversed(active_test.automated_seq)] - test_widget_box.remove(notest_label) - as_widget = make_automated_seq_widget(active_test) - test_widget_box.add(as_widget) - window.show_all() - command = None - while command != 'quit_automated_seq': - active_subtest = subtest_queue.pop() - active_subtest.label_box.update_status(_ACTIVE) - gtk.main() - command = control_recv() - XXX_log('ui automated_seq step (%s)' % command) - refresh_test_status(status_file_path, test_list) - test_widget_box.queue_draw() - test_widget_box.remove(as_widget) - test_widget_box.add(notest_label) - window.show_all() - XXX_log('ui exiting automated_seq') - else: - gtk.main() - refresh_test_status(status_file_path, test_list) - - # Tell the control process we are done. - control_send((None, 0)) - - XXX_log('exiting ui') - -if __name__ == '__main__': - - # In global scope, get the test_data class description from the - # control program -- this allows a convenient single point of - # definition for this class. - test_data_class_def = control_recv() - exec(test_data_class_def) - - main()