Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Side by Side Diff: client/bin/factory_ui

Issue 3104020: Refactor -- make ui passive watcher, control a passive test list. (Closed) Base URL: http://src.chromium.org/git/autotest.git
Patch Set: rebase against ToT Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « client/bin/factory.py ('k') | client/bin/factory_ui_lib.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # 2 #
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 7
8 # DESCRIPTION : 8 # DESCRIPTION :
9 # 9 #
10 # This UI is intended to be used by the factory autotest suite to 10 # This UI is intended to be used by the factory autotest suite to
11 # provide factory operators feedback on test status and control over 11 # provide factory operators feedback on test status and control over
12 # execution order. 12 # execution order.
13 # 13 #
14 # In short, the UI is composed of a 'console' panel on the bottom of 14 # In short, the UI is composed of a 'console' panel on the bottom of
15 # the screen which displays the autotest log, and there is also a 15 # the screen which displays the autotest log, and there is also a
16 # 'test list' panel on the right hand side of the screen. The 16 # 'test list' panel on the right hand side of the screen. The
17 # majority of the screen is dedicated to tests, which are executed in 17 # majority of the screen is dedicated to tests, which are executed in
18 # seperate processes, but instructed to display their own UIs in this 18 # seperate processes, but instructed to display their own UIs in this
19 # dedicated area whenever possible. Tests in the test list are 19 # dedicated area whenever possible. Tests in the test list are
20 # executed in order by default, but can be activated on demand via 20 # executed in order by default, but can be activated on demand via
21 # associated keyboard shortcuts (triggers). As tests are run, their 21 # associated keyboard shortcuts. As tests are run, their status is
22 # status is color-indicated to the operator -- greyed out means 22 # color-indicated to the operator -- greyed out means untested, yellow
23 # untested, yellow means active, green passed and red failed. 23 # means active, green passed and red failed.
24 24
25 25
26 import gobject 26 import gobject
27 import gtk 27 import gtk
28 import imp 28 import imp
29 import os 29 import os
30 import pango 30 import pango
31 import subprocess 31 import subprocess
32 import sys 32 import sys
33 import time 33 import time
34 34
35 import common 35 import common
36 import factory 36 import factory
37 import factory_ui_lib as ful 37 import factory_ui_lib as ful
38 38
39 from factory import TestData 39
40 # These definitions are expose these classes directly into this
41 # namespace, so that the test_list that is sent from the control file
42 # can have cleaner syntax. These are done in this fashion, as opposed
43 # to "from factory import <class>" to work-around Python namespace
44 # wackiness -- the from syntax does not work, creating new classes.
45 OperatorTest = factory.OperatorTest
46 InformationScreen = factory.InformationScreen
47 AutomatedSequence = factory.AutomatedSequence
48 AutomatedSubTest = factory.AutomatedSubTest
49 AutomatedRebootSubTest = factory.AutomatedRebootSubTest
40 50
41 51
42 _SEP_COLOR = gtk.gdk.color_parse('grey50') 52 _SEP_COLOR = gtk.gdk.color_parse('grey50')
43 53
44 _LABEL_EN_SIZE = (160, 35) 54 _LABEL_EN_SIZE = (170, 35)
45 _LABEL_ZW_SIZE = (70, 35) 55 _LABEL_ZW_SIZE = (70, 35)
46 _LABEL_EN_FONT = pango.FontDescription('courier new extra-condensed 16') 56 _LABEL_EN_FONT = pango.FontDescription('courier new extra-condensed 16')
47 _LABEL_ZW_FONT = pango.FontDescription('normal 12') 57 _LABEL_ZW_FONT = pango.FontDescription('normal 12')
48 _LABEL_T_SIZE = (30, 35) 58 _LABEL_T_SIZE = (30, 35)
49 _LABEL_T_FONT = pango.FontDescription('courier new italic ultra-condensed 10') 59 _LABEL_T_FONT = pango.FontDescription('courier new italic ultra-condensed 10')
50 _LABEL_UNTESTED_FG = gtk.gdk.color_parse('grey40') 60 _LABEL_UNTESTED_FG = gtk.gdk.color_parse('grey40')
51 _LABEL_TROUGH_COLOR = gtk.gdk.color_parse('grey20') 61 _LABEL_TROUGH_COLOR = gtk.gdk.color_parse('grey20')
52 _LABEL_STATUS_SIZE = (140, 30) 62 _LABEL_STATUS_SIZE = (140, 30)
53 _LABEL_STATUS_FONT = pango.FontDescription( 63 _LABEL_STATUS_FONT = pango.FontDescription(
54 'courier new bold extra-condensed 16') 64 'courier new bold extra-condensed 16')
55 _OTHER_LABEL_FONT = pango.FontDescription('courier new condensed 20') 65 _OTHER_LABEL_FONT = pango.FontDescription('courier new condensed 20')
56 66
57 _ST_LABEL_EN_SIZE = (250, 35) 67 _ST_LABEL_EN_SIZE = (250, 35)
58 _ST_LABEL_ZW_SIZE = (150, 35) 68 _ST_LABEL_ZW_SIZE = (150, 35)
59 69
60 _STATUS_REFRESH_MS = 200 70 _STATUS_REFRESH_MS = 100
61 71
62 class Console: 72 class Console:
63 '''Display a progress log. Implemented by launching an borderless 73 '''Display a progress log. Implemented by launching an borderless
64 xterm at a strategic location, and running tail against the log.''' 74 xterm at a strategic location, and running tail against the log.'''
65 75
66 def __init__(self, allocation): 76 def __init__(self, allocation):
67 xterm_coords = '135x14+%d+%d' % (allocation.x, allocation.y) 77 xterm_coords = '135x14+%d+%d' % (allocation.x, allocation.y)
68 factory.log('xterm_coords = %s' % xterm_coords) 78 factory.log('xterm_coords = %s' % xterm_coords)
69 xterm_cmd = (('aterm --geometry %s -bw 0 -e bash -c ' % 79 xterm_cmd = (('aterm --geometry %s -bw 0 -e bash -c ' %
70 xterm_coords).split() + 80 xterm_coords).split() +
71 ['tail -f %s | grep FACTORY' % factory.LOG_PATH]) 81 ['tail -f %s | grep FACTORY' % factory.LOG_PATH])
72 factory.log('xterm_cmd = %s' % xterm_cmd) 82 factory.log('xterm_cmd = %s' % xterm_cmd)
73 self._proc = subprocess.Popen(xterm_cmd) 83 self._proc = subprocess.Popen(xterm_cmd)
74 84
75 def __del__(self): 85 def __del__(self):
76 factory.log('console_proc __del__') 86 factory.log('console_proc __del__')
77 self._proc.kill() 87 self._proc.kill()
78 88
79 89
80 # Routines to communicate with the autotest control file, using python
81 # expressions. The stdin_callback assures notification for any new
82 # messages.
83
84 def stdin_callback(s, c):
85 factory.log('stdin_callback, quitting gtk main')
86 gtk.main_quit()
87 return True
88
89 def control_recv():
90 return eval(sys.stdin.readline().rstrip())
91
92 def control_send(x):
93 print repr(x)
94 sys.stdout.flush()
95
96 def control_send_target_test_update(test, count):
97 factory.log('ui send_target_test_update %s.%s_%s' %
98 (test.formal_name, test.tag_prefix, count))
99 control_send((test.formal_name, test.tag_prefix, count))
100
101
102 # Capture keyboard events here for debugging -- under normal 90 # Capture keyboard events here for debugging -- under normal
103 # circumstances, all keyboard events should be captured by executing 91 # circumstances, all keyboard events should be captured by executing
104 # tests, and hence this should not be called. 92 # tests, and hence this should not be called.
105 93
106 def handle_key_release_event(_, event): 94 def handle_key_release_event(_, event):
107 factory.log('base ui key event (%s)' % event.keyval) 95 factory.log('base ui key event (%s)' % event.keyval)
108 return True 96 return True
109 97
110 98
111 class TestLabelBox(gtk.EventBox): 99 class TestLabelBox(gtk.EventBox):
112 100
113 def __init__(self, test): 101 def __init__(self, test):
114 gtk.EventBox.__init__(self) 102 gtk.EventBox.__init__(self)
115 self.modify_bg(gtk.STATE_NORMAL, ful.LABEL_COLORS[ful.UNTESTED]) 103 self.modify_bg(gtk.STATE_NORMAL, ful.LABEL_COLORS[ful.UNTESTED])
116 label_en = gtk.Label(test.label_en) 104
117 label_en.set_size_request(*_LABEL_EN_SIZE) 105 label_en = ful.make_label(test.label_en, size=_LABEL_EN_SIZE,
118 label_en.modify_font(_LABEL_EN_FONT) 106 font=_LABEL_EN_FONT, alignment=(0.5, 0.5),
119 label_en.set_alignment(0.5, 0.5) 107 fg=_LABEL_UNTESTED_FG)
120 label_en.modify_fg(gtk.STATE_NORMAL, _LABEL_UNTESTED_FG) 108 label_zw = ful.make_label(test.label_zw, size=_LABEL_ZW_SIZE,
121 label_zw = gtk.Label(test.label_zw) 109 font=_LABEL_ZW_FONT, alignment=(0.5, 0.5),
122 label_zw.set_size_request(*_LABEL_ZW_SIZE) 110 fg=_LABEL_UNTESTED_FG)
123 label_zw.modify_font(_LABEL_ZW_FONT) 111 label_t = ful.make_label('C-' + test.kbd_shortcut, size=_LABEL_T_SIZE,
124 label_zw.set_alignment(0.5, 0.5) 112 font=_LABEL_T_FONT, alignment=(0.5, 0.5),
125 label_zw.modify_fg(gtk.STATE_NORMAL, _LABEL_UNTESTED_FG) 113 fg=ful.BLACK)
126 label_t = gtk.Label('C-' + test.trigger)
127 label_t.set_size_request(*_LABEL_T_SIZE)
128 label_t.modify_font(_LABEL_T_FONT)
129 label_t.set_alignment(0.5, 0.5)
130 label_t.modify_fg(gtk.STATE_NORMAL, ful.BLACK)
131 hbox = gtk.HBox() 114 hbox = gtk.HBox()
132 hbox.pack_start(label_en, False, False) 115 hbox.pack_start(label_en, False, False)
133 hbox.pack_start(label_zw, False, False) 116 hbox.pack_start(label_zw, False, False)
134 hbox.pack_start(label_t, False, False) 117 hbox.pack_start(label_t, False, False)
135 self.add(hbox) 118 self.add(hbox)
136 self.label_list = [label_en, label_zw] 119 self.label_list = [label_en, label_zw]
137 120
138 def update(self, status): 121 def update(self, status):
139 label_fg = status == ful.UNTESTED and _LABEL_UNTESTED_FG or ful.BLACK 122 label_fg = status == ful.UNTESTED and _LABEL_UNTESTED_FG or ful.BLACK
140 for label in self.label_list: 123 for label in self.label_list:
141 label.modify_fg(gtk.STATE_NORMAL, label_fg) 124 label.modify_fg(gtk.STATE_NORMAL, label_fg)
142 self.modify_bg(gtk.STATE_NORMAL, ful.LABEL_COLORS[status]) 125 self.modify_bg(gtk.STATE_NORMAL, ful.LABEL_COLORS[status])
143 self.queue_draw() 126 self.queue_draw()
144 127
145 128
146 class SubTestLabelBox(gtk.EventBox): 129 class SubTestLabelBox(gtk.EventBox):
147 130
148 def __init__(self, test): 131 def __init__(self, test):
149 gtk.EventBox.__init__(self) 132 gtk.EventBox.__init__(self)
150 self.modify_bg(gtk.STATE_NORMAL, ful.BLACK) 133 self.modify_bg(gtk.STATE_NORMAL, ful.BLACK)
151 label_status = gtk.Label(ful.UNTESTED) 134 label_status = ful.make_label(ful.UNTESTED, size=_LABEL_STATUS_SIZE,
152 label_status.set_size_request(*_LABEL_STATUS_SIZE) 135 alignment=(0, 0.5),
153 label_status.set_alignment(0, 0.5) 136 font=_LABEL_STATUS_FONT,
154 label_status.modify_font(_LABEL_STATUS_FONT) 137 fg=_LABEL_UNTESTED_FG)
155 label_status.modify_fg(gtk.STATE_NORMAL, _LABEL_UNTESTED_FG) 138 label_sep = ful.make_label(' : ', alignment=(0.5, 0.5),
156 label_sep = gtk.Label(' : ') 139 font=_LABEL_EN_FONT)
157 label_sep.set_alignment(0.5, 0.5) 140 label_en = ful.make_label(test.label_en, size=_ST_LABEL_EN_SIZE,
158 label_sep.modify_font(_LABEL_EN_FONT) 141 alignment=(0.5, 0.5),
159 label_sep.modify_fg(gtk.STATE_NORMAL, ful.LIGHT_GREEN) 142 font=_LABEL_EN_FONT)
160 label_en = gtk.Label(test.label_en) 143 label_zw = ful.make_label(test.label_zw, size=_ST_LABEL_ZW_SIZE,
161 label_en.set_size_request(*_ST_LABEL_EN_SIZE) 144 alignment=(0.5, 0.5), font=_LABEL_ZW_FONT)
162 label_en.set_alignment(0.5, 0.5)
163 label_en.modify_font(_LABEL_EN_FONT)
164 label_en.modify_fg(gtk.STATE_NORMAL, ful.LIGHT_GREEN)
165 label_zw = gtk.Label(test.label_zw)
166 label_zw.set_size_request(*_ST_LABEL_ZW_SIZE)
167 label_zw.set_alignment(0.5, 0.5)
168 label_zw.modify_font(_LABEL_ZW_FONT)
169 label_zw.modify_fg(gtk.STATE_NORMAL, ful.LIGHT_GREEN)
170 hbox = gtk.HBox() 145 hbox = gtk.HBox()
171 hbox.pack_end(label_status, False, False) 146 hbox.pack_end(label_status, False, False)
172 hbox.pack_end(label_sep, False, False) 147 hbox.pack_end(label_sep, False, False)
173 hbox.pack_end(label_zw, False, False) 148 hbox.pack_end(label_zw, False, False)
174 hbox.pack_end(label_en, False, False) 149 hbox.pack_end(label_en, False, False)
175 self.add(hbox) 150 self.add(hbox)
176 self.label_status = label_status 151 self.label_status = label_status
177 152
178 def update(self, status): 153 def update(self, status):
179 if status == ful.UNTESTED: 154 if status == ful.UNTESTED:
180 return 155 return
181 self.label_status.set_text(status) 156 self.label_status.set_text(status)
182 self.label_status.modify_fg(gtk.STATE_NORMAL, ful.LABEL_COLORS[status]) 157 self.label_status.modify_fg(gtk.STATE_NORMAL, ful.LABEL_COLORS[status])
183 self.queue_draw() 158 self.queue_draw()
184 159
185 160
161 class UiState():
162
163 def __init__(self, window, status_map, test_widget_box):
164
165 def make_empty_test_label_widget():
166 label_box = gtk.EventBox()
167 label_box.modify_bg(gtk.STATE_NORMAL, ful.BLACK)
168 label = ful.make_label('no active test', font=_OTHER_LABEL_FONT,
169 alignment=(0.5, 0.5))
170 label_box.add(label)
171 return label_box
172
173 def make_automated_seq_label_widget(subtest_list):
174 vbox = gtk.VBox()
175 vbox.set_spacing(0)
176 for subtest in subtest_list:
177 label_box = SubTestLabelBox(subtest)
178 status_map.set_label_box(subtest, label_box)
179 vbox.pack_start(status_map.lookup_label_box(subtest),
180 False, False)
181 return vbox
182
183 self._window = window
184 self._status_map = status_map
185 self._test_widget_box = test_widget_box
186 self._empty_test_widget = make_empty_test_label_widget()
187 self._active_test_widget = self._empty_test_widget
188 self.active_test = None
189
190 self._test_widget_box.add(self._empty_test_widget)
191
192 self._automated_seq_widget_map = dict(
193 (t, make_automated_seq_label_widget(t.subtest_list))
194 for t in self._status_map.test_db.seq_test_set)
195
196 def set_active_test(self, test):
197 '''Control what kind of widget is shown in the testing area of
198 the screen. For normal operator tests, this is just a label
199 saying there is no active test. The expectation is that the
200 operator test itself has a window obscuring this message. For
201 automated sequences, since there is no other window, the no
202 active test message is replaced with an updated list of
203 subtest status.'''
204 if test == self.active_test:
205 return
206 self.active_test = test
207 self._test_widget_box.remove(self._active_test_widget)
208 active_widget = (test in self._status_map.test_db.seq_test_set
209 and self._automated_seq_widget_map[test]
210 or self._empty_test_widget)
211 self._test_widget_box.add(active_widget)
212 self._active_test_widget = active_widget
213 self._window.show_all()
214
215
186 def make_hsep(width=1): 216 def make_hsep(width=1):
187 frame = gtk.EventBox() 217 frame = gtk.EventBox()
188 frame.set_size_request(-1, width) 218 frame.set_size_request(-1, width)
189 frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR) 219 frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR)
190 return frame 220 return frame
191 221
192 222
193 def make_vsep(width=1): 223 def make_vsep(width=1):
194 frame = gtk.EventBox() 224 frame = gtk.EventBox()
195 frame.set_size_request(width, -1) 225 frame.set_size_request(width, -1)
196 frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR) 226 frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR)
197 return frame 227 return frame
198 228
199 229
200 def make_notest_label(): 230 def refresh_status(status_map, ui_state):
201 label = gtk.Label('no active test') 231 status_map.read_new_data()
202 label.modify_font(_OTHER_LABEL_FONT) 232 active_test = status_map.get_active_top_level_test()
203 label.set_alignment(0.5, 0.5) 233 ui_state.set_active_test(active_test)
204 label.modify_fg(gtk.STATE_NORMAL, ful.LIGHT_GREEN) 234 return True
205 box = gtk.EventBox()
206 box.modify_bg(gtk.STATE_NORMAL, ful.BLACK)
207 box.add(label)
208 return box
209
210
211 def make_automated_seq_widget(as_test, status_map):
212 vbox = gtk.VBox()
213 vbox.set_spacing(0)
214 map(lambda st: vbox.pack_start(status_map.lookup_label(st), False, False),
215 as_test.automated_seq)
216 return vbox
217 235
218 236
219 def main(): 237 def main():
238 '''This process is launched by the autotest suite_Factory control
239 process. Communication with this process is an exchange of well
240 formed python expressions over stdin and stdout. Basically
241 sending wraps arguments in a call to repr() and recv calls eval()
242 to re-generate the python data.'''
243
244 def control_recv():
245 return eval(sys.stdin.readline().rstrip())
246
247 def control_send(x):
248 print repr(x)
249 sys.stdout.flush()
250
251 # On startup, get the list of tests to run (in order) and the
252 # autotest status file path.
253 factory.log('pulling control info')
254 test_list = control_recv()
255 status_file_path = control_recv()
256
257 status_map = factory.StatusMap(test_list, status_file_path)
258
220 window = gtk.Window(gtk.WINDOW_TOPLEVEL) 259 window = gtk.Window(gtk.WINDOW_TOPLEVEL)
221 window.connect('destroy', lambda _: gtk.main_quit()) 260 window.connect('destroy', lambda _: gtk.main_quit())
222 window.modify_bg(gtk.STATE_NORMAL, ful.BLACK) 261 window.modify_bg(gtk.STATE_NORMAL, ful.BLACK)
223 262
224 screen = window.get_screen() 263 screen = window.get_screen()
225 screen_size = (screen.get_width(), screen.get_height()) 264 screen_size = (screen.get_width(), screen.get_height())
226 window.set_size_request(*screen_size) 265 window.set_size_request(*screen_size)
227 266
228 label_trough = gtk.VBox() 267 label_trough = gtk.VBox()
229 label_trough.set_spacing(0) 268 label_trough.set_spacing(0)
230 269
231 rhs_box = gtk.EventBox() 270 rhs_box = gtk.EventBox()
232 rhs_box.modify_bg(gtk.STATE_NORMAL, _LABEL_TROUGH_COLOR) 271 rhs_box.modify_bg(gtk.STATE_NORMAL, _LABEL_TROUGH_COLOR)
233 rhs_box.add(label_trough) 272 rhs_box.add(label_trough)
234 273
235 console_box = gtk.EventBox() 274 console_box = gtk.EventBox()
236 console_box.set_size_request(-1, 180) 275 console_box.set_size_request(-1, 180)
237 console_box.modify_bg(gtk.STATE_NORMAL, ful.BLACK) 276 console_box.modify_bg(gtk.STATE_NORMAL, ful.BLACK)
238 277
239 notest_label = make_notest_label()
240
241 test_widget_box = gtk.Alignment(xalign=0.5, yalign=0.5) 278 test_widget_box = gtk.Alignment(xalign=0.5, yalign=0.5)
242 test_widget_box.set_size_request(-1, -1) 279 test_widget_box.set_size_request(-1, -1)
243 test_widget_box.add(notest_label) 280
281 ui_state = UiState(window, status_map, test_widget_box)
244 282
245 lhs_box = gtk.VBox() 283 lhs_box = gtk.VBox()
246 lhs_box.pack_end(console_box, False, False) 284 lhs_box.pack_end(console_box, False, False)
247 lhs_box.pack_start(test_widget_box) 285 lhs_box.pack_start(test_widget_box)
248 lhs_box.pack_start(make_hsep(3), False, False) 286 lhs_box.pack_start(make_hsep(3), False, False)
249 287
250 base_box = gtk.HBox() 288 base_box = gtk.HBox()
251 base_box.pack_end(rhs_box, False, False) 289 base_box.pack_end(rhs_box, False, False)
252 base_box.pack_end(make_vsep(3), False, False) 290 base_box.pack_end(make_vsep(3), False, False)
253 base_box.pack_start(lhs_box) 291 base_box.pack_start(lhs_box)
254 292
255 window.connect('key-release-event', handle_key_release_event) 293 window.connect('key-release-event', handle_key_release_event)
256 window.add_events(gtk.gdk.KEY_RELEASE_MASK) 294 window.add_events(gtk.gdk.KEY_RELEASE_MASK)
257 295
258 # On startup, get general configuration data from the autotest 296 gobject.timeout_add(_STATUS_REFRESH_MS, refresh_status,
259 # control program, specifically the list of tests to run (in 297 status_map, ui_state)
260 # order) and some filenames.
261 factory.log('pulling control info')
262 test_list = control_recv()
263 status_file_path = control_recv()
264
265 status_map = ful.StatusMap(status_file_path, test_list)
266 gobject.timeout_add(_STATUS_REFRESH_MS, status_map.read_new_data)
267 298
268 for test in test_list: 299 for test in test_list:
269 tlb = TestLabelBox(test) 300 label_box = TestLabelBox(test)
270 status_map.set_label(test, tlb) 301 status_map.set_label_box(test, label_box)
271 label_trough.pack_start(tlb, False, False) 302 label_trough.pack_start(label_box, False, False)
272 label_trough.pack_start(make_hsep(), False, False) 303 label_trough.pack_start(make_hsep(), False, False)
273 for subtest in test.automated_seq:
274 stlb = SubTestLabelBox(subtest)
275 status_map.set_label(subtest, stlb)
276 304
277 window.add(base_box) 305 window.add(base_box)
278 window.show_all() 306 window.show_all()
279 307
280 ful.hide_cursor(window.window) 308 ful.hide_cursor(window.window)
281 309
282 test_widget_allocation = test_widget_box.get_allocation() 310 test_widget_allocation = test_widget_box.get_allocation()
283 test_widget_size = (test_widget_allocation.width, 311 test_widget_size = (test_widget_allocation.width,
284 test_widget_allocation.height) 312 test_widget_allocation.height)
285 factory.log('test_widget_size = %s' % repr(test_widget_size)) 313 factory.log('test_widget_size = %s' % repr(test_widget_size))
286 control_send(test_widget_size) 314 control_send(test_widget_size)
287 315
288 trigger_dict = dict((test.trigger, test) for test in test_list)
289
290 gobject.io_add_watch(sys.stdin, gobject.IO_IN, stdin_callback)
291
292 console = Console(console_box.get_allocation()) 316 console = Console(console_box.get_allocation())
293 317
294 factory.log('finished ui setup') 318 factory.log('factory_ui setup done, starting gtk.main()...')
295 319
296 # Test selection is driven either by triggers or by the 320 gtk.main()
297 # remaining_tests_queue. If a trigger was seen, explicitly run
298 # the corresponding test. Otherwise choose the next test from the
299 # queue. Tests are removed from the queue as they are run,
300 # regarless of the outcome. Tests that are interrupted by trigger
301 # are treated as having failed.
302 #
303 # Iterations in the main loop here are driven by data availability
304 # on stdin, which is used to communicate with the autotest control
305 # program. On each step through the loop, a trigger is received
306 # (possibly None) to indicate how the next test should be selected.
307 321
308 while True: 322 factory.log('factory_ui gtk.main() finished, exiting.')
309 command, arg = control_recv()
310 factory.log('ui received command %s(%s)' % (command, arg))
311 if command == 'switch_to':
312 next_test = trigger_dict.get(arg, None)
313 elif command == 'next_test':
314 next_test = status_map.next_untested()
315 else:
316 factory.log('ui command unknown, exiting...')
317 break
318 control_send_target_test_update(
319 next_test, status_map.lookup_count(next_test) + 1)
320 if next_test.automated_seq:
321 factory.log('ui starting automated_seq')
322 test_widget_box.remove(notest_label)
323 as_widget = make_automated_seq_widget(next_test, status_map)
324 test_widget_box.add(as_widget)
325 window.show_all()
326 gtk.main()
327 command = control_recv()
328 factory.log('ui automated_seq cmd (%s)' % command)
329 test_widget_box.remove(as_widget)
330 test_widget_box.add(notest_label)
331 window.show_all()
332 factory.log('ui exiting automated_seq')
333 else:
334 gtk.main()
335
336 # Tell the control process we are done.
337 control_send((None, 0))
338
339 factory.log('exiting ui')
340 323
341 if __name__ == '__main__': 324 if __name__ == '__main__':
342 main() 325 main()
OLDNEW
« no previous file with comments | « client/bin/factory.py ('k') | client/bin/factory_ui_lib.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698