1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
#!/usr/bin/python
# a mostly output-only ui for runin tests
import os
import signal
from gi.repository import Gtk, Gdk, GObject
class Monitor:
""" a status file monitor, sets up a signal handler so that the
parent runin-tests can notify us of a new status file, then on the
next update cycle we read the status file and delete it"""
def __init__(self):
self.dirty = True
self._name = os.getenv('RUNIN_STATUS')
if not self._name:
self._name = '/tmp/runin.status'
signal.signal(signal.SIGUSR1, self._monitor_signal_cb)
def _monitor_signal_cb(self, a, b):
self.dirty = True
def readlines(self):
self.dirty = False
try:
f = open(self._name, 'r')
x = f.readlines()
f.close()
os.remove(self._name)
except IOError:
x = []
pass
return x
class Window:
def __init__(self):
self.window = Gtk.Window(Gtk.WindowType.POPUP)
self.window.set_default_size(1200, 900 - 480 - 2)
self.window.set_border_width(10)
# a heading, identifying the program
self.heading = Gtk.Label(self.make_heading())
# a progress bar
self.progress = Gtk.ProgressBar()
# a table for progress detail
self.rows = 8
self.columns = 2
self.table = Gtk.Table(rows=self.rows, columns=self.columns)
self.table.set_col_spacings(6)
self.table.labels = {}
for row in range(self.rows):
for column in range(self.columns):
label = Gtk.Label('(%d,%d) ####################' %
(column, row))
if column == 0:
label.set_alignment(1.0, 0.5)
else:
label.set_alignment(0.0, 0.5)
label.show()
self.table.labels[row, column] = label
self.table.attach(label, column, column+1, row, row+1)
# lay the above out vertically
self.box = Gtk.VBox()
self.box.set_spacing(10)
self.box.add(self.heading)
self.box.add(self.progress)
self.box.add(self.table)
self.heading.show()
self.progress.show()
self.table.show()
self.box.show()
self.window.add(self.box)
self.window.connect("key-press-event", self._key_press_event_cb)
self.window.connect("delete_event", self._delete_event_cb)
self.window.connect("destroy", self._destroy_cb)
# position the window against the lower right of screen
self.window.set_gravity(Gdk.Gravity.SOUTH_EAST)
width, height = self.window.get_size()
self.window.move(Gdk.Screen.width() - width,
Gdk.Screen.height() - height)
self.window.show()
self._monitor = Monitor()
GObject.timeout_add(100, self._monitor_timeout_cb)
self.progress.grab_focus()
def make_heading(self):
""" generate heading text """
package = 'olpc-runin-tests'
version = os.getenv('RUNIN_VERSION')
if not version:
try:
version = open('/runin/runin-tests', 'r').readlines()[5].split('"')[1]
except IOError:
version = ''
# olpc-os-builder.git:modules/base/kspost.10.version_number.sh
# "$majver.$minver.$relver for ${platform}${custstr} (build $buildnr)"
try:
build = open('/boot/olpc_build', 'r').readline().rstrip().split('(')[1].split(')')[0]
except (IndexError,IOError):
build = ''
try:
kernel = 'kernel ' + open('/proc/sys/kernel/osrelease', 'r').readline().rstrip().split('-')[2]
except (IndexError,IOError):
kernel = ''
if kernel == '':
try:
kernel = 'kernel ' + open('/proc/sys/kernel/osrelease', 'r').readline().rstrip().split('-')[1].split('.')[3]
except (IndexError,IOError):
kernel = ''
try:
ofw = 'firmware ' + open('/proc/device-tree/openprom/model','r').readline()[6:13].rstrip()
except (IndexError,IOError):
ofw = ''
try:
ec = 'EC ' + open('/proc/device-tree/ec-name','r').readline()[:-1]
except IOError:
ec = ''
text = '%s %s %s %s %s %s ' % (package, version, build, kernel, ofw, ec)
return text
def main(self):
try:
Gtk.main()
except KeyboardInterrupt:
pass
def stop(self):
ENABLE_STOP = os.getenv('ENABLE_STOP')
if (ENABLE_STOP is None) or ('TRUE' not in ENABLE_STOP.upper()):
return False
RUNIN_PATH = os.getenv('RUNIN_PATH')
if not RUNIN_PATH:
RUNIN_PATH = '/runin'
open(os.path.join(RUNIN_PATH, 'stop'), 'w').close()
return True
def _key_press_event_cb(self, window, event, data=None):
if event.keyval == 32: # space bar
self.stop()
return False
def _delete_event_cb(self, widget, event, data=None):
Gtk.main_quit()
return False
def _destroy_cb(self, widget, data=None):
Gtk.main_quit()
def _monitor_timeout_cb(self):
if self._monitor.dirty:
# read the data from the file
lines = self._monitor.readlines()
# process the data
row = 0
for line in lines:
line = line.rstrip()
if not line.startswith('@@'):
# put the data into the table rows
if row < self.rows:
(name, value) = line.split('@', 2)[0:2]
self.table.labels[row, 0].set_text(name)
self.table.labels[row, 1].set_text(value)
row += 1
else:
# update the progress bar
(here, there) = line.split(' ', 3)[1:3]
self.progress.set_fraction(float(here) / float(there))
# erase the remainder of the table rows
while row < self.rows:
self.table.labels[row, 0].set_text('')
self.table.labels[row, 1].set_text('')
row += 1
return True
if __name__ == "__main__":
window = Window()
window.main()
|