xwm/core: internal windows now create a GtkWindow
[luccawm.git] / xwm / test / test.py
blobdb79fd429cee1b54ad967aa20ceb795e3ca5c599
2 import subprocess
3 import sys
4 import thread
5 import traceback
6 import signal
7 import os
8 import time
10 import gtk
11 import gobject
13 LUCCA_STATE_HIDDEN = '8'
15 def alarm_signal(signal, stackframe):
16 raise Exception("timeout")
17 signal.signal(signal.SIGALRM, alarm_signal)
19 def nongtk_thread():
20 global proc
21 proc = subprocess.Popen(sys.argv[1], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
23 logfile = open(sys.argv[3], 'w')
25 tests_failed = False
27 def send(line):
28 logfile.write('> %s\n' % line)
29 proc.stdin.write('%s\n' % line)
31 def getline():
32 signal.alarm(5)
33 line = proc.stdout.readline().rstrip('\n')
34 signal.alarm(0)
35 logfile.write('< %s\n' % line)
36 return line.split(' ')
38 try:
39 line = getline()
40 display = line[0]
42 #create an "existing" window that xwm should map once it's connected to the display
43 def create_window():
44 global gtkwindow1
45 gtkwindow1 = gtk.Window()
46 gtkwindow1.set_title("test_window_1")
47 gtkwindow1.set_geometry_hints(None, min_width=10, min_height=11)
48 gtkwindow1.show()
49 do_in_gtk_thread(create_window)
51 send('getb %s valid' % display)
52 line = getline()
53 assert(line[0] == '0')
55 send('connect')
56 line = getline()
57 assert(line[0] == 'new-screen')
58 screen = line[1]
59 line = getline()
60 assert(line[0] == 'new-window')
61 luccawindow1 = line[1]
63 send('getb %s valid' % display)
64 line = getline()
65 assert(line[0] == '1')
67 send('get_default_screen')
68 line = getline()
69 assert(line[0] == screen)
71 send('getb %s valid' % screen)
72 line = getline()
73 assert(line[0] == '1')
75 send('screen_get_display %s' % screen)
76 line = getline()
77 assert(line[0] == display)
79 send('getui %s width' % screen)
80 line = getline()
81 screen_width = int(line[0])
82 send('getui %s height' % screen)
83 line = getline()
84 screen_height = int(line[0])
86 send('getui %s workarea-x' % screen)
87 line = getline()
88 assert(line[0] == '0')
89 send('getui %s workarea-y' % screen)
90 line = getline()
91 assert(line[0] == '0')
92 send('getui %s workarea-width' % screen)
93 line = getline()
94 assert(int(line[0]) == screen_width)
95 send('getui %s workarea-height' % screen)
96 line = getline()
97 assert(int(line[0]) == screen_height)
99 send('getstr %s requested-title' % luccawindow1)
100 line = getline()
101 assert(line[0] == "test_window_1")
103 send('get_geometry_hints %s' % luccawindow1)
104 line = getline()
105 assert(line[0] == "min_size")
106 assert(line[1] == "10")
107 assert(line[2] == "11")
108 line = getline()
109 assert(line[0] == "end_geometry")
111 send('get_requested_states %s' % luccawindow1)
112 line = getline()
113 assert(len(line) == 1)
115 #configure the existing (already mapped) window
116 send('get_root %s' % screen)
117 line = getline()
118 root = line[0]
120 configure_mutex = thread.allocate_lock()
121 configure_mutex.acquire()
122 def set_configure_event():
123 def timeout():
124 logfile.write("ERROR: timeout waiting for configure event\n")
125 tests_failed = True
126 thread.interrupt_main()
127 configure_mutex.release()
129 source = gobject.timeout_add(5000, timeout)
131 def on_configure(widget, event):
132 frame = gtkwindow1.window.get_frame_extents()
133 logfile.write(":window configured with xywh %s %s %s %s\n" % (frame.x, frame.y, frame.width, frame.height))
135 if not (frame.x == 12 and frame.y == 13 and frame.width == 32 and frame.height == 33):
136 tests_failed = True
137 thread.interrupt_main()
139 gobject.source_remove(source)
140 configure_mutex.release()
142 gtkwindow1.connect('configure-event', on_configure)
144 do_in_gtk_thread(set_configure_event)
146 send('configure %s %s %s %s %s %s %s' % (luccawindow1, root, 12, 13, 32, 33, 1))
147 configure_mutex.acquire()
149 #create a new window that xwm should recognize wants to be mapped
150 def create_window():
151 global gtkwindow2
152 gtkwindow2 = gtk.Window()
153 gtkwindow2.iconify()
154 gtkwindow2.set_title("test_window_2")
155 gtkwindow2.show()
156 do_in_gtk_thread(create_window)
158 line = getline()
159 assert(line[0] == 'new-window')
160 luccawindow2 = line[1]
162 send('getstr %s requested-title' % luccawindow2)
163 line = getline()
164 assert(line[0] == "test_window_2")
166 send('get_requested_states %s' % luccawindow2)
167 line = getline()
168 assert(line[0] == LUCCA_STATE_HIDDEN)
169 assert(len(line) == 2)
171 #map the new window
172 map_mutex = thread.allocate_lock()
173 map_mutex.acquire()
174 def set_map_event():
175 def timeout():
176 logfile.write("ERROR: timeout waiting for map event\n")
177 tests_failed = True
178 thread.interrupt_main()
179 map_mutex.release()
181 source = gobject.timeout_add(5000, timeout)
183 def on_map(widget, event):
184 frame = gtkwindow2.window.get_frame_extents()
185 logfile.write(":window mapped with xywh %s %s %s %s\n" % (frame.x, frame.y, frame.width, frame.height))
187 if not (frame.x == 10 and frame.y == 11 and frame.width == 30 and frame.height == 31):
188 tests_failed = True
189 thread.interrupt_main()
191 gobject.source_remove(source)
192 map_mutex.release()
194 gtkwindow2.connect('map-event', on_map)
196 do_in_gtk_thread(set_map_event)
198 send('configure %s %s %s %s %s %s %s' % (luccawindow2, root, 10, 11, 30, 31, 1))
199 map_mutex.acquire()
201 #unmap the new window
202 unmap_mutex = thread.allocate_lock()
203 unmap_mutex.acquire()
204 def set_unmap_event():
205 def timeout():
206 logfile.write("ERROR: timeout waiting for unmap event\n")
207 tests_failed = True
208 thread.interrupt_main()
209 unmap_mutex.release()
211 source = gobject.timeout_add(5000, timeout)
213 def on_unmap(widget, event):
214 frame = gtkwindow2.window.get_frame_extents()
215 logfile.write(":window unmapped\n")
217 gobject.source_remove(source)
218 unmap_mutex.release()
220 gtkwindow2.connect('unmap-event', on_unmap)
222 do_in_gtk_thread(set_unmap_event)
224 send('configure %s %s %s %s %s %s %s' % (luccawindow2, root, 10, 11, 30, 31, 0))
225 unmap_mutex.acquire()
227 #create an xclock window, which doesn't set WM_NAME
228 xclock = subprocess.Popen("xclock")
230 try:
231 line = getline()
232 assert(line[0] == 'new-window')
233 xclockwindow = line[1]
235 send('getstr %s requested-title' % xclockwindow)
236 line = getline()
237 assert(line[0] == "xclock")
239 send('get_windows')
240 line = getline()
241 assert(set(line) == set([luccawindow1, luccawindow2, xclockwindow, '']))
242 finally:
243 os.kill(xclock.pid, signal.SIGTERM)
245 send('disconnect')
247 send('getb %s valid' % screen)
248 line = getline()
249 assert(line[0] == '0')
251 except:
252 tests_failed = True
254 traceback.print_exc(None, logfile)
257 proc.stdin.close()
259 if tests_failed:
260 os.kill(proc.pid, signal.SIGTERM)
262 result, stdout, stderr = proc.wait(), proc.stdout.read(), proc.stderr.read()
264 logfile.write("Test process return value: %s\n" % result)
266 logfile.write("Stdout:\n%s" % stdout)
267 logfile.write("Stderr:\n%s" % stderr)
269 logfile.close()
271 if result != 0 or stderr != '':
272 tests_failed = True
274 do_in_gtk_thread(gtk.main_quit)
276 if tests_failed:
277 print "Unit test failed; see %s for details" % sys.argv[3]
278 sys.exit(1)
279 else:
280 f = open(sys.argv[2], 'w')
281 f.close()
284 def do_in_gtk_thread(f, *args, **kwargs):
285 lock = thread.allocate_lock()
286 lock.acquire()
287 def idle_func():
288 f(*args, **kwargs)
289 lock.release()
290 gobject.idle_add(idle_func)
291 lock.acquire()
293 def gtk_thread():
294 gtk.gdk.threads_enter()
295 gtk.main()
296 gtk.gdk.threads_leave()
298 gtk.gdk.threads_init()
300 thread.start_new_thread(gtk_thread, ())
302 nongtk_thread()