]> git.lyx.org Git - lyx.git/blob - development/keystest/autolyx
bf9f48ad1fbba58b5bc1459d72d1e9af68801ed5
[lyx.git] / development / keystest / autolyx
1 #!/bin/bash
2 # This script starts LyX, and restarts LyX if it is closed
3 # it logs all output, including backtraces to development/keystest/out/GDB
4
5 #Setting the following may give better screen shots
6 #gconftool-2 /apps/metacity/general/compositing_manager -s -t bool true
7
8 DIRNAME0=`dirname "$0"`
9 OUTDIR="$DIRNAME0/out"
10 ROOT_OUTDIR="$DIRNAME0/out"
11 THIS_PID=$$
12
13 EXE_TO_TEST=src/lyx
14
15 if [ ! -e "$EXE_TO_TEST" ]
16 then
17         echo "$EXE_TO_TEST" does not exist
18         echo Cannot proceed
19         exit
20 fi
21
22 #BORED_AFTER_SECS=7200 #If we have spend more than 3600 secs (an hour) replaying a file, without learning anything new, go and start looking for more bugs instead
23 BORED_AFTER_SECS=3600 #If we have spend more than 3600 secs (an hour) replaying a file, without learning anything new, go and start looking for more bugs instead
24
25 LAST_CORE=""
26
27 #############################
28 # This section of code is LyX Specific
29 #############################
30
31 if [ ! -e $DIRNAME0/.lyx ]
32 then
33         echo WARNING $DIRNAME0/.lyx does not exist
34         echo will need to regenerate .lyx every test
35 fi
36
37 #if [ ! -e lib/doc.orig ]
38 #then
39 #       mv lib/doc lib/doc.orig
40 #fi
41
42 kill_all_children() {
43         kill `list_all_children.sh $1`
44         sleep 0.1
45         kill -9 `list_all_children.sh $1`
46 }
47
48
49
50 ensure_cannot_print () {
51 if [ ! -z "$REPLAYFILE" ]
52 then
53         return
54 fi
55 if lpq
56 then
57  
58         echo We can print, this is bad!
59         echo use lpadmin to stop keytest from destroying a forest.
60         full_exit
61         sleep 999999 ; read
62 else
63         echo "Phew, lpq reckons we aren't ready to print. This is a *good* thing!"
64 fi
65 }
66
67 extras_save () {
68  return 
69  for f in `ls lib/doc`
70  do
71         if [ lib/doc/$f -nt lib/doc.orig/$f -o ! -e lib/doc.orig/$f ]
72         then 
73                 #echo making doc dir $OUTDIR/$SEC.doc
74                 mkdir -p $OUTDIR/$SEC.doc
75                 cp -a lib/doc/$f $OUTDIR/$SEC.doc/
76         fi
77  done
78 }
79
80 extras_prepare () {
81         return
82         mkdir -p lib/doc/
83         rm lib/doc/*.lyx
84         cp -p lib/doc.orig/*.lyx lib/doc/
85 }
86
87 get_crash_id () {
88   name=`(cat $GDB | grep -o ' in lyx::[[:alnum:]:]*' ; cat $GDB | grep -o ' [ai][nt] [[:alnum:]:]*' ) | head -n3 | sed s/in// | sed 's/ //g'`
89   echo $name | sed 's/ /__/g'
90 }
91
92 calc_confirm_file() {
93         id=`get_crash_id`
94         echo "$ROOT_OUTDIR/$id.reproduced"
95 }
96
97 get_pid () {
98         sleep 3
99         echo getting pidof "$1" 1>&2
100         #PID=`ps "-u$USER" "$2" | grep "$1" | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'`
101         PID=`ps x | grep "$1" | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'`
102         echo "$PID" | ( grep " " > /dev/null && ( echo too many PIDs 1>&2 ; full_exit ) )
103         nPIDs=`echo PID "$PID" | wc -l`
104         echo nPIDs $nPIDs 1>&2
105         sleep 1
106         echo -- if [ "$nPIDs" != "1" ] 1>&2
107         if test "$nPIDs" != "1" #2> /tmp/testerr
108         then 
109                 echo autolyx: Wrong number of PIDs "$nPIDs" "($1)" "($2)" 1>&2
110         fi
111         echo "$PID"
112         echo got pidof "$1" 1>&2
113 }
114 clean_up () {
115         KT_PID=`get_pid keytest.py x`
116         kill $KT_PID
117         sleep 0.1
118         kill -9 $KT_PID
119 }
120
121 full_exit() {
122         clean_up
123
124         echo attempting to exit this entire script... normal exit may just exit one function
125
126         kill $THIS_PID
127         sleep 1
128         echo We should not get this far
129         sleep 1
130         kill -9 $THIS_PID
131         echo We really should not get this far 
132         exit
133 }
134
135 run_gdb () {
136   echo Starting GDB
137   (echo "
138   shell svn info src/
139   run
140   bt
141   shell kill $CHILD_PID
142   shell wmctrl -l
143   shell sleep 1
144   shell kill -9 $CHILD_PID
145 " ; yes q) | HOME="$NEWHOME" gdb src/lyx 2>&1 | strings|  tee $GDB
146   echo "end run_gdb"
147   #### gcore $GDB.core
148   #shell wmctrl -r __renamed__ -b add,shaded
149   #shell wmctrl -r term -b add,shaded
150   #shell wmctrl -r term -b add,shaded
151   #shell wmctrl -R lyx' 
152   #
153   #shell import -window root '$GDB.png'
154   #shell import -window root '$GDB..png'
155   #exit
156 }
157
158
159 ###########################
160
161
162
163 try_replay () {
164         id=`get_crash_id`
165         echo CRASH_ID 
166         export CONFIRM_FILE=`calc_confirm_file`
167         if [ ! -e "$CONFIRM_FILE" ]
168         then
169                 echo $CONFIRM_FILE does not exist
170                 echo This bug appears not to have been reproduced before
171                 echo Will try to reproduce now
172                 echo
173                 do_replay
174                 echo 
175                 echo Finished attempt at replay
176         else
177                 echo $CONFIRM_FILE exists
178                 echo This bugs has already been reproduced
179                 echo Will not attempt to reproduce again
180         fi
181 }
182
183 do_replay() {
184         (REPLAYFILE="$KEYCODEpure" TAIL_LINES=25 MAX_TAIL_LINES=10000 bash "$0")&
185         TEST_PID="$!"
186         echo Backgrounded $TEST_PID
187         echo waiting for $TEST_PID to finish
188         wait "$TEST_PID" 
189 }
190
191 test_replayed () {
192         test -e "$f.replay/last_crash_sec" -o -e "$f.replay/Irreproducible" 
193 }
194
195 move_to_replayed () {
196         mkdir -p $REPLAY_DIR/replayed
197         mv $f* $REPLAY_DIR/replayed
198 }
199
200 do_queued_replays() {
201 REPLAY_DIR=development/keytest/out/toreplay
202 for f in `ls $REPLAY_DIR/*KEYCODEpure`
203 do
204         if test_replayed
205         then
206                 move_to_replayed
207         else
208                 #./development/keytest/killtest
209                 killall lyx
210                 sleep 1
211                 killall -9 lyx
212                 KEYCODEpure="$f" do_replay
213                 #if test_replayed 
214                 #then 
215                 move_to_replayed
216                 #fi
217         fi
218         
219 done
220 }
221
222 #get_pid() {
223 #            ps a | grep $1 | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'
224 #}
225
226 do_one_test() {
227   GDB=$OUTDIR/$SEC.GDB
228   KEYCODE=$OUTDIR/$SEC.KEYCODE
229   KEYCODEpure=$OUTDIR/$SEC.KEYCODEpure
230   NEWHOME=~/kt.dir/$SEC.dir
231   mkdir -p $NEWHOME
232   NEWHOME=`cd $NEWHOME; pwd`
233   echo NEWHOME $NEWHOME
234   mkdir -p "$NEWHOME"
235   cp -rv $DIRNAME0/.lyx "$NEWHOME"/
236   killall -9 lyx latex pdflatex
237   ( sleep 9 &&
238      ps a | grep lyx 
239         echo -- 1 || full_exit
240      LYX_PID=""
241      i=0
242      echo -- while [ -z "$LYX_PID" -a 200 -gt $i ]
243      while [ -z "$LYX_PID" -a 200 -gt $i ]
244      do
245              #export LYX_PID=`ps a | grep /src/lyx | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'`
246              export LYX_PID=`get_pid "/src/lyx$" `
247              echo LYXPID "$LYX_PID" || full_exit
248              sleep 0.1
249              i=$(($i+1))
250      done 
251      echo `ps a | grep /src/lyx`
252         echo -- 2
253      echo `ps a | grep /src/lyx | grep -v grep`
254         echo -- 3
255      echo `ps a | grep /src/lyx | grep -v grep | sed 's/ [a-z].*$//'`
256         echo -- 4
257      echo LYX_PID=$LYX_PID
258      echo XA_PRIMARY | xclip -selection XA_PRIMARY
259      echo XA_SECONDARY | xclip -selection XA_SECONDARY
260      echo XA_CLIPBOARD | xclip -selection XA_CLIPBOARD
261
262      echo -- if [ ! -z "$LYX_PID" ]
263      if [ ! -z "$LYX_PID" ]
264      then
265          kill `ps a | grep keytest.py | grep -v grep | cut -c 1-5`
266          sleep 0.2
267          kill -9 `ps a | grep keytest.py | grep -v grep | cut -c 1-5`
268         while ! wmctrl -r lyx -b add,maximized_vert,maximized_horz
269         do
270                 echo trying to maximize lyx
271                 sleep 1
272         done
273          KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py | tee $KEYCODE
274          #echo "$!" > $NEWHOME/keytest_py.pid
275      fi
276      killall lyx) &
277   CHILD_PID="$!"
278   ls src/lyx ; sleep 1
279    pwd
280   
281   #You may want to use the following to simulate SIGFPE
282   #(sleep 90 && killall -8 lyx) &
283   echo TTL $TAIL_LINES
284   extras_prepare
285   ensure_cannot_print
286   run_gdb
287 #  (run_gdb) &
288 #  GDBTASK_PID="$!"
289 #  (sleep 600 ; kill "$!")      
290 #  echo WAITING FOR: wait $GDBTASK_PID
291 #  wait $GDBTASK_PID
292 #  echo NOLONGER waiting for: wait $GDBTASK_PID
293
294   echo END gdb
295   kill $CHILD_PID
296   KT_PID=`get_pid keytest.py`
297   echo KT_PID=$KT_PID
298   kill $KT_PID
299   sleep 0.3
300   kill -9 $CHILD_PID
301   kill -9 $KT_PID
302   # Or use "exited normally":
303   echo END gdb2
304   # these tend to take up a huge amount of space:
305   rm -rf $NEWHOME
306   if (grep " signal SIG[^TK]" $GDB || grep KILL_FREEZE $KEYCODE)
307   then
308     extras_save
309     mkdir -p $OUTDIR/save && (
310             ln $OUTDIR/$SEC.* $OUTDIR/save ||
311             cp $OUTDIR/$SEC.* $OUTDIR/save)
312     LAST_CRASH_SEC=$SEC
313     echo $LAST_CRASH_SEC > $OUTDIR/last_crash_sec
314     if [ ! -z "$TAIL_LINES" ]
315     then
316         LAST_EVENT="$SEC"
317         echo Reproducible > $OUTDIR/Reproducible
318     fi
319     TAIL_LINES="" 
320     if [ -z "$REPLAYFILE" ]
321     then
322         echo ATTEMPTING TO REPLAY
323         try_replay
324     else
325         export KEYTEST_INFILE=$KEYCODEpure
326         NUM_KEYCODES=`wc -l < $KEYCODEpure`
327         echo NUM_KEYCODES $NUM_KEYCODES, was $LAST_NUM_KEYCODES
328         if [ "$NUM_KEYCODES" != "$LAST_NUM_KEYCODES" ]
329         then
330                 LAST_EVENT="$SEC"
331                 LAST_NUM_KEYCODES=$NUM_KEYCODES
332                 echo "Hooray! we have eleminated some keycodes"
333         fi
334     fi
335     if [ ! -z "$AND_THEN_QUIT" ]
336     then
337                 RESULT=1
338                 echo RR 1
339                 return 1
340     fi
341     if [ ! -z "$LAST_CORE" ]
342     then
343       rm "$LAST_CORE"
344     fi
345     LAST_CORE="$GDB.core"
346   else
347     rm -rf $BAK/* 
348     mv $OUTDIR/$SEC.* $BAK/
349     if [ ! -z "$TAIL_LINES" ]
350      then
351         echo TTL3 $TAIL_LINES
352         echo MAX_TAIL_LINES "$MAX_TAIL_LINES"
353         TAIL_LINES=$(($TAIL_LINES*2))
354         echo TTL4 $TAIL_LINES
355         if [ "$TAIL_LINES" -ge "0$MAX_TAIL_LINES" -a ! -z "$MAX_TAIL_LINES" ]
356         then
357                 echo Giving up because $TAIL_LINES '>' $MAX_TAIL_LINES
358                 echo Irreproducible > $OUTDIR/Irreproducible
359                 full_exit
360         fi
361     fi
362     if [ ! -z "$AND_THEN_QUIT" ]
363     then
364                 RESULT=0
365                 echo RR 0
366                 return 0
367     fi
368
369     echo TTL2 $TAIL_LINES
370   fi
371 }
372
373 if [ ! -z "$1" ]
374 then
375         REPLAYFILE=$1
376 fi
377
378 if [ ! -z "$REPLAYFILE" ]
379 then
380         echo REPLAYMODE
381         OUTDIR="$REPLAYFILE.replay/"
382         mkdir -p $REPLAYFILE.replay/ || full_exit
383         export KEYTEST_INFILE=$REPLAYFILE
384         if [ ! -e "$REPLAYFILE" ]
385         then
386                 echo "$REPLAYFILE" does not exist
387                 echo exiting
388                 full_exit 1
389         fi
390 else
391         do_queued_replays
392         echo RANDOM MODE
393 fi
394
395 get_pid [0-9].x-session-manager"$" x
396 export X_PID=`get_pid [0-9].x-session-manager x`
397 echo X_PID $X_PID
398
399 export TAIL_LINES=$TAIL_LINES
400 echo TL $TAIL_LINES
401
402
403 BAK="$OUTDIR/backup"
404 mkdir -p $BAK
405
406         
407
408
409 #rename other windows to avoid confusion.
410 wmctrl -N __renamed__ -r lyx
411 wmctrl -N __renamed__ -r lyx
412 wmctrl -N __renamed__ -r lyx
413 wmctrl -N __renamed__ -r lyx
414 export PATH=`cd $DIRNAME0; pwd`/path:$PATH
415
416 if [ ! -z "$1" ]
417 then
418   SEC=`date +%s`
419   export MAX_DROP=0
420   if [ ".$SCREENSHOT_OUT." = ".auto." ]
421   then
422         echo SCREENSHOT_OUT was $SCREENSHOT_OUT.
423         export SCREENSHOT_OUT="$OUTDIR/$SEC.s"
424         echo SCREENSHOT_OUT is $SCREENSHOT_OUT.
425         #exit
426   fi
427   export RESULT=179
428   do_one_test #| tee do_one_test.log
429   RESULT="$?"
430   echo Ressult $RESULT
431
432   kill `list_all_children.sh $$`
433   sleep 0.1
434   kill -9 `list_all_children.sh $$`
435
436   exit $RESULT
437   
438   #echo done ; sleep 1
439   full_exit
440 fi
441
442
443
444 (
445 echo TTL $TAIL_LINES
446
447 LAST_EVENT=`date +%s` # Last time something interesting happened. If nothing interesting has happened for a while, we should quit.
448
449 ensure_cannot_print
450 echo X_PID $X_PID
451 export X_PID=`get_pid [0-9].x-session-manager"$" x`
452 echo PATH $PATH
453 while true
454 do
455  echo Currently running autolyx PID=$$
456  if [ ! -z "$TAIL_LINES" ] 
457  then
458   echo TAIL_LINES: "$TAIL_LINES"
459   TAIL_FILE=$OUTDIR/tail_"$TAIL_LINES"
460   tail -n "$TAIL_LINES" "$REPLAYFILE" > $TAIL_FILE
461   KEYTEST_INFILE=$TAIL_FILE
462   MAX_DROP=0
463  else
464   MAX_DROP=0.2
465  fi
466  export MAX_DROP
467   SEC=`date +%s`
468  if [ ! -z "$REPLAYFILE" ] 
469  then
470         echo Boredom factor: $SEC-$LAST_EVENT'=' $(($SEC-$LAST_EVENT))
471         if [ $(($SEC-$LAST_EVENT)) -gt $BORED_AFTER_SECS ]
472         then
473                 echo
474                 echo Is is now $SEC seconds
475                 echo The last time we managed to eliminate a keycode was at $LAST_EVENT
476                 echo We get bored after $BORED_AFTER_SECS seconds
477                 echo Giving up now.
478                 echo
479                 echo $LAST_CRASH_SEC > $OUTDIR/Finished
480                 mkdir $OUTDIR/final
481                 ln $OUTDIR/$SEC* $OUTDIR/final || cp $OUTDIR/$SEC* $OUTDIR/final
482                 CONFIRM_FILE=`calc_confirm_file`
483                 echo Reproducible > "$CONFIRM_FILE"
484                 
485                 
486                 full_exit
487         fi
488  else
489         do_queued_replays
490  fi
491  do_one_test
492 done
493 kill_all_children $$
494 ) 2>&1 |tee $OUTDIR/log
495 kill_all_children $$