]> git.lyx.org Git - lyx.git/blob - development/keystest/shared_functions.sh
Don't need this.
[lyx.git] / development / keystest / shared_functions.sh
1 DIRNAME0=`dirname "$0"`
2 #ROOT_OUTDIR="$DIRNAME0/out"
3 OUTDIR="$ROOT_OUTDIR"
4 #OUTDIR="$DIRNAME0/out"
5 THIS_PID=$$
6
7 SRC_DIR=lyx/src
8 EXE_TO_TEST=$SRC_DIR/lyx
9
10 #kill(){
11 #       echo kill
12 #}
13 #killall (){
14 #       echo killall
15 #}
16
17 mkdirp () {
18         mkdir -p "$1"
19         chmod g+w "$1"
20
21
22 kill_all_children() {
23         kill `$DIRNAME0/list_all_children.sh $1`
24         sleep 0.1
25         kill -9 `$DIRNAME0/list_all_children.sh $1`
26 }
27
28
29 #BORED_AFTER_SECS=7200 #If we have spent more than 3600 secs (an hour) replaying a file, without learning anything new, go and start looking for more bugs instead
30 if [ -z $BORED_AFTER_SECS ]
31 then
32         BORED_AFTER_SECS=3600 #If we have spent more than 3600 secs (an hour) replaying a file, without learning anything new, go and start looking for more bugs instead
33 fi
34
35 LAST_CORE=""
36
37 #############################
38 # This section of code is LyX Specific
39 #############################
40
41 if [ ! -e $DIRNAME0/.lyx ]
42 then
43         echo WARNING $DIRNAME0/.lyx does not exist
44         echo will need to regenerate .lyx every test
45 fi
46
47 #if [ ! -e lib/doc.orig ]
48 #then
49 #       mv lib/doc lib/doc.orig
50 #fi
51
52 #kill_all_children() {
53 #        kill `$DIRNAME0/list_all_children.sh $1`
54 #        sleep 0.1
55 #        kill -9 `$DIRNAME0/list_all_children.sh $1`
56 #}
57
58 #. $DIRNAME0/shared_functions.sh
59
60
61 ensure_cannot_print () {
62 if [ ! -z "$REPLAYFILE" ]
63 then
64         return
65 fi
66 if lpq
67 then
68  
69         echo We can print, this is bad!
70         echo use lpadmin to stop keytest from destroying a forest.
71         full_exit
72         sleep 999999 ; read
73 else
74         echo "Phew, lpq reckons we aren't ready to print. This is a *good* thing!"
75 fi
76 }
77
78 extras_save () {
79  return 
80  for f in `ls lib/doc`
81  do
82         if [ lib/doc/$f -nt lib/doc.orig/$f -o ! -e lib/doc.orig/$f ]
83         then 
84                 #echo making doc dir $OUTDIR/$SEC.doc
85                 mkdirp $OUTDIR/$SEC.doc
86                 cp -a lib/doc/$f $OUTDIR/$SEC.doc/
87         fi
88  done
89 }
90
91 extras_prepare () {
92         return
93         mkdirp lib/doc/
94         rm lib/doc/*.lyx
95         cp -p lib/doc.orig/*.lyx lib/doc/
96 }
97
98 get_crash_id () {
99   name=`(cat $GDB | grep -o ' in lyx::[[:alnum:]:]*' ; cat $GDB | grep -o ' [ai][nt] [[:alnum:]:]*' ) | head -n3 | sed s/in// | sed 's/ //g'`
100   echo $name | sed 's/ /__/g'
101 }
102
103 calc_confirm_file() {
104         id=`get_crash_id`
105         echo "$ROOT_OUTDIR/$id.reproduced"
106 }
107
108 get_pid () {
109         sleep 3
110         echo getting pidof "$1" 1>&2
111         #PID=`ps "-u$USER" "$2" | grep "$1" | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'`
112         PID=`ps x | grep "$1" | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'`
113         echo "$PID" | ( grep " " > /dev/null && ( echo ERROR too many PIDs 1>&2 ; ps x ; full_exit ) )
114         nPIDs=`echo PID "$PID" | wc -l`
115         echo nPIDs $nPIDs 1>&2
116         sleep 1
117         echo -- if [ "$nPIDs" != "1" ] 1>&2
118         if test "$nPIDs" != "1" #2> /tmp/testerr
119         then 
120                 echo autolyx: Wrong number of PIDs "$nPIDs" "($1)" "($2)" 1>&2
121                 echo autolyx: PIDs "$PID" 1>&2
122                 ps x 1>&2
123                 echo -----
124         fi
125         echo "$PID"
126         echo got pidof "$1" 1>&2
127 }
128 clean_up () {
129         KT_PID=`get_pid keytest.py x`
130         kill $KT_PID
131         sleep 0.1
132         kill -9 $KT_PID
133 }
134
135 full_exit() {
136         clean_up
137
138         echo attempting to exit this entire script... normal exit may just exit one function
139
140         kill $THIS_PID
141         sleep 1
142         echo We should not get this far
143         sleep 1
144         kill -9 $THIS_PID
145         echo We really should not get this far 
146         exit
147 }
148
149 run_gdb () {
150   #Spawn a process to kill lyx if it runs too long
151   if ! touch $GDB
152   then
153         echo cannot touch $GDB
154         full_exit
155   fi
156   (sleep 300; echo KILLER ACTIVATIED ;killall gdb lyx ; sleep 1 ; killall -9 gdb lyx)&
157   KILLER_PID=$!
158   echo KILLING LYX, before starting new lyx
159   killall lyx
160   sleep 1 
161   killall lyx -9
162   sleep 1
163   echo Starting GDB
164   #shell svn info $SRC_DIR/
165   (echo "
166   run
167   bt
168   #shell kill $CHILD_PID
169   shell wmctrl -l
170   #shell sleep 1
171   #shell kill -9 $CHILD_PID
172 " ; yes q) | HOME="$NEWHOME" gdb $EXE_TO_TEST 2>&1 | strings|  tee $GDB
173   echo "end run_gdb ($KILLER_PID)"
174   kill $KILLER_PID
175   sleep 0.1
176   kill -9 $KILLER_PID
177
178   #### gcore $GDB.core
179   #shell wmctrl -r __renamed__ -b add,shaded
180   #shell wmctrl -r term -b add,shaded
181   #shell wmctrl -r term -b add,shaded
182   #shell wmctrl -R lyx' 
183   #
184   #shell import -window root '$GDB.png'
185   #shell import -window root '$GDB..png'
186   #exit
187 }
188
189
190 ###########################
191
192
193
194 try_replay () {
195         id=`get_crash_id`
196         echo CRASH_ID 
197         export CONFIRM_FILE=`calc_confirm_file`
198         if [ ! -e "$CONFIRM_FILE" ]
199         then
200                 echo $CONFIRM_FILE does not exist
201                 echo This bug appears not to have been reproduced before
202                 echo Will try to reproduce now
203                 echo
204                 do_replay
205                 echo 
206                 echo Finished attempt at replay
207         else
208                 echo $CONFIRM_FILE exists
209                 echo This bugs has already been reproduced
210                 echo Will not attempt to reproduce again
211         fi
212 }
213
214 do_replay() {
215         (REPLAYFILE="$KEYCODEpure" TAIL_LINES=25 MAX_TAIL_LINES=10000 bash "$0")&
216         TEST_PID="$!"
217         echo Backgrounded $TEST_PID
218         echo waiting for $TEST_PID to finish
219         wait "$TEST_PID" 
220 }
221
222 test_replayed () {
223         test -e "$f.replay/last_crash_sec" -o -e "$f.replay/Irreproducible" 
224 }
225
226 move_to_replayed () {
227         mkdirp $REPLAY_DIR/replayed
228         mv $f* $REPLAY_DIR/replayed
229 }
230
231 do_queued_replay() {
232         if test_replayed
233         then
234                 move_to_replayed
235         else
236                 #./development/keytest/killtest
237                 killall lyx
238                 sleep 1
239                 echo killall -9 lyx
240                 killall -9 lyx
241                 KEYCODEpure="$f" do_replay
242                 #if test_replayed 
243                 #then 
244                 move_to_replayed
245                 #fi
246         fi
247 }
248
249 do_queued_replays() {
250 REPLAY_DIR=$OUTDIR/toreplay
251 echo doing queued_replays
252 echo replays `ls $REPLAY_DIR/*KEYCODEpure`
253 for f in `ls $REPLAY_DIR/*KEYCODEpure`
254 do
255         do_queued_replay
256 done
257 echo done queued_replays
258 (
259   REPLAY_DIR=$OUTDIR/toreproduce
260   export BORED_AFTER_SECS=0
261   echo doing queued_reproduce
262   echo reproduce`ls $REPLAY_DIR/*KEYCODEpure`
263   for f in `ls $REPLAY_DIR/*KEYCODEpure`
264   do
265         do_queued_replay
266   done
267   echo done queued_reproduce
268 )
269 }
270
271 #get_pid() {
272 #            ps a | grep $1 | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'
273 #}
274
275 get_version_info() {
276         (cd $SRC_DIR ; svn info) 2>&1 |tee "$1".svn
277         $EXE_TO_TEST -version 2>&1 "$1".version
278 }
279
280 do_one_test() {
281   GDB=$OUTDIR/$SEC.GDB
282   KEYCODE=$OUTDIR/$SEC.KEYCODE
283   KEYCODEpure=$OUTDIR/$SEC.KEYCODEpure
284   NEWHOME=~/kt.dir/$SEC.dir
285   mkdirp $NEWHOME
286   NEWHOME=`cd $NEWHOME; pwd`
287   echo NEWHOME $NEWHOME
288   mkdirp "$NEWHOME"
289   cp -rv $DIRNAME0/.lyx "$NEWHOME"/
290   echo killall -9 lyx latex pdflatex
291   killall -9 lyx latex pdflatex
292   ( sleep 9 &&
293      ps a | grep lyx 
294         echo -- 1 || full_exit
295      LYX_PID=""
296      i=0
297      echo -- while [ -z "$LYX_PID" -a 200 -gt $i ]
298      while [ -z "$LYX_PID" -a 200 -gt $i ]
299      do
300              #export LYX_PID=`ps a | grep /src/lyx | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'`
301              export LYX_PID=`get_pid "$EXE_TO_TEST$" `
302              echo LYXPID "$LYX_PID" || full_exit
303              sleep 0.1
304              i=$(($i+1))
305      done 
306      echo `ps a | grep $EXE_TO_TEST`
307         echo -- 2
308      echo `ps a | grep $EXE_TO_TEST | grep -v grep`
309         echo -- 3
310      echo `ps a | grep $EXE_TO_TEST | grep -v grep | sed 's/ [a-z].*$//'`
311         echo -- 4
312      echo LYX_PID=$LYX_PID
313      echo XA_PRIMARY | xclip -selection XA_PRIMARY
314      echo XA_SECONDARY | xclip -selection XA_SECONDARY
315      echo XA_CLIPBOARD | xclip -selection XA_CLIPBOARD
316
317      echo -- if [ ! -z "$LYX_PID" ]
318      if [ ! -z "$LYX_PID" ]
319      then
320          kill `ps a | grep keytest.py | grep -v grep | cut -c 1-5`
321          sleep 0.2
322          kill -9 `ps a | grep keytest.py | grep -v grep | cut -c 1-5`
323         while ! wmctrl -r lyx -b add,maximized_vert,maximized_horz
324         do
325                 echo trying to maximize lyx
326                 sleep 1
327         done
328          echo BEGIN KEYTEST KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py
329          KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py | tee $KEYCODE
330          #echo "$!" > $NEWHOME/keytest_py.pid
331          echo END_KEYTEST
332      fi
333      echo NO_KEYTEST
334      echo killall lyx
335      killall lyx
336      sleep 0.1
337      kill -9 "$LYX_PID"
338      killall -9 lyx #sometimes LyX really doesn't want to die causing the script to freeze
339      #killall lyx #sometimes LyX really doesn't want to die causing the script to freeze
340      sleep 1
341      #kill -9 "$LYX_PID" #sometimes LyX really doesn't want to die causing the script to freeze
342
343      #sleep 1 
344      #killall -9 lyx
345      ) &
346   CHILD_PID="$!"
347   ls $EXE_TO_TEST ; sleep 1
348    pwd
349   
350   #You may want to use the following to simulate SIGFPE
351   #(sleep 90 && killall -8 lyx) &
352   echo TTL $TAIL_LINES
353   extras_prepare
354   ensure_cannot_print
355   run_gdb
356 #  (run_gdb) &
357 #  GDBTASK_PID="$!"
358 #  (sleep 600 ; kill "$!")      
359 #  echo WAITING FOR: wait $GDBTASK_PID
360 #  wait $GDBTASK_PID
361 #  echo NOLONGER waiting for: wait $GDBTASK_PID
362
363   echo END gdb
364   kill $CHILD_PID
365   KT_PID=`get_pid keytest.py`
366   echo KT_PID=$KT_PID
367   kill $KT_PID
368   sleep 0.3
369   kill -9 $CHILD_PID
370   kill -9 $KT_PID
371   # Or use "exited normally":
372   echo END gdb2
373   # these tend to take up a huge amount of space:
374   echo will erase "$NEWHOME"
375   sleep 2
376   rm -rf $NEWHOME
377   if (grep " signal SIG[^TK]" $GDB || grep KILL_FREEZE $KEYCODE)
378   then
379     extras_save
380     mkdirp $OUTDIR/save && (
381             ln $OUTDIR/$SEC.* $OUTDIR/save ||
382             cp $OUTDIR/$SEC.* $OUTDIR/save)
383     LAST_CRASH_SEC=$SEC
384     echo $LAST_CRASH_SEC > $OUTDIR/last_crash_sec
385     get_version_info $OUTDIR/last_crash_sec.info
386     if [ ! -z "$TAIL_LINES" ]
387     then
388         LAST_EVENT="$SEC"
389         echo Reproducible > $OUTDIR/Reproducible
390     fi
391     TAIL_LINES="" 
392     if [ -z "$REPLAYFILE" ]
393     then
394         echo ATTEMPTING TO REPLAY
395         try_replay
396     else
397         export KEYTEST_INFILE=$KEYCODEpure
398         NUM_KEYCODES=`wc -l < $KEYCODEpure`
399         echo NUM_KEYCODES $NUM_KEYCODES, was $LAST_NUM_KEYCODES
400         if [ "$NUM_KEYCODES" != "$LAST_NUM_KEYCODES" ]
401         then
402                 LAST_EVENT="$SEC"
403                 LAST_NUM_KEYCODES=$NUM_KEYCODES
404                 echo "Hooray! we have eleminated some keycodes"
405         fi
406     fi
407     if [ ! -z "$AND_THEN_QUIT" ]
408     then
409                 RESULT=1
410                 echo RR 1
411                 return 1
412     fi
413     if [ ! -z "$LAST_CORE" ]
414     then
415       rm "$LAST_CORE"
416     fi
417     LAST_CORE="$GDB.core"
418   else
419     if ! test -z "$BAK"
420     then
421           echo will erase '$BAK/*'="'$BAK/*'"
422           sleep 2
423           rm -rf $BAK/*
424           mv $OUTDIR/$SEC.* $BAK/
425     else
426           echo "BAK is null"
427     fi
428     if [ ! -z "$TAIL_LINES" ]
429      then
430         echo TTL3 $TAIL_LINES
431         echo MAX_TAIL_LINES "$MAX_TAIL_LINES"
432         TAIL_LINES=$(($TAIL_LINES*2))
433         echo TTL4 $TAIL_LINES
434         if [ "$TAIL_LINES" -ge "0$MAX_TAIL_LINES" -a ! -z "$MAX_TAIL_LINES" ]
435         then
436                 echo Giving up because $TAIL_LINES '>' $MAX_TAIL_LINES
437                 echo Irreproducible > $OUTDIR/Irreproducible
438                 full_exit
439         fi
440     fi
441     if [ ! -z "$AND_THEN_QUIT" ]
442     then
443                 RESULT=0
444                 echo RR 0
445                 return 0
446     fi
447
448     echo TTL2 $TAIL_LINES
449   fi
450 }
451
452 test_exist () {
453         if [ ! -e "$1" ]
454         then    
455                 echo "$1" does not exist!
456                 full_exit 1
457         fi
458 }
459
460 assert () {
461         if ! "$@"
462         then 
463                 echo "Assertion '$*' Failed!"
464                 full_exit 1
465         fi
466 }
467         
468
469
470 #####################################################
471 # MAIN
472 #####################################################
473
474 #Start basic sanity checks
475
476 autolyx_main () {
477
478 if [ ! -e "$EXE_TO_TEST" ]
479 then
480         echo "$EXE_TO_TEST" does not exist
481         echo Cannot proceed
482         exit
483 fi
484
485 assert which xvkbd
486 assert which wmctrl
487
488 if ! wmctrl -l > /dev/null 
489 then
490         echo autolyx: cannot run wmctrl -l
491         exit
492 fi
493
494 test_exist "$EXE_TO_TEST"
495 test_exist "$DIRNAME0/keytest.py"
496
497 if ! test -z "`pylint -e $DIRNAME0/keytest.py`" 
498 then
499         echo  "$DIRNAME0/keytest.py" has python errors
500         exit
501 fi
502
503 ensure_cannot_print
504
505 #End basic sanity checks
506
507 if [ ! -z "$1" ]
508 then
509         REPLAYFILE=$1
510 fi
511
512 if [ ! -z "$REPLAYFILE" ]
513 then
514         echo REPLAYMODE
515         OUTDIR="$REPLAYFILE.replay/"
516         mkdirp $REPLAYFILE.replay/ || full_exit
517         export KEYTEST_INFILE=$REPLAYFILE
518         if [ ! -e "$REPLAYFILE" ]
519         then
520                 echo "$REPLAYFILE" does not exist
521                 echo exiting
522                 full_exit 1
523         fi
524 else
525         do_queued_replays
526         echo RANDOM MODE
527 fi
528
529 get_pid [0-9].x-session-manager"$" x
530 export X_PID=`get_pid [0-9].x-session-manager x`
531 echo X_PID $X_PID
532
533 export TAIL_LINES=$TAIL_LINES
534 echo TL $TAIL_LINES
535
536
537 BAK="$OUTDIR/backup"
538 mkdirp $BAK
539
540         
541
542
543 #rename other windows to avoid confusion.
544 wmctrl -N __renamed__ -r lyx
545 wmctrl -N __renamed__ -r lyx
546 wmctrl -N __renamed__ -r lyx
547 wmctrl -N __renamed__ -r lyx
548 export PATH=`cd $DIRNAME0; pwd`/path:$PATH
549
550 if [ ! -z "$1" ]
551 then
552   SEC=`date +%s`
553   export MAX_DROP=0
554   if [ ".$SCREENSHOT_OUT." = ".auto." ]
555   then
556         echo SCREENSHOT_OUT was $SCREENSHOT_OUT.
557         export SCREENSHOT_OUT="$OUTDIR/$SEC.s"
558         echo SCREENSHOT_OUT is $SCREENSHOT_OUT.
559         #exit
560   fi
561   export RESULT=179
562   do_one_test #| tee do_one_test.log
563   RESULT="$?"
564   echo Ressult $RESULT
565
566   kill `list_all_children.sh $$`
567   sleep 0.1
568   kill -9 `list_all_children.sh $$`
569
570   exit $RESULT
571   
572   #echo done ; sleep 1
573   full_exit
574 fi
575
576
577
578 (
579 echo TTL $TAIL_LINES
580
581 LAST_EVENT=`date +%s` # Last time something interesting happened. If nothing interesting has happened for a while, we should quit.
582
583 ensure_cannot_print
584 echo X_PID $X_PID
585 export X_PID=`get_pid [0-9].x-session-manager"$" x`
586 echo PATH $PATH
587 while true
588 do
589  echo Currently running autolyx PID=$$
590  if [ ! -z "$TAIL_LINES" ] 
591  then
592   echo TAIL_LINES: "$TAIL_LINES"
593   TAIL_FILE=$OUTDIR/tail_"$TAIL_LINES"
594   tail -n "$TAIL_LINES" "$REPLAYFILE" > $TAIL_FILE
595   KEYTEST_INFILE=$TAIL_FILE
596   MAX_DROP=0
597  else
598   MAX_DROP=0.2
599  fi
600  export MAX_DROP
601   SEC=`date +%s`
602  if [ -z "$TAIL_LINES" -a ! -z "$REPLAYFILE" ] 
603  then
604         echo Boredom factor: $SEC-$LAST_EVENT'=' $(($SEC-$LAST_EVENT))
605         if [ $(($SEC-$LAST_EVENT)) -gt $BORED_AFTER_SECS ]
606         then
607                 echo
608                 echo Is is now $SEC seconds
609                 echo The last time we managed to eliminate a keycode was at $LAST_EVENT
610                 echo We get bored after $BORED_AFTER_SECS seconds
611                 echo Giving up now.
612                 echo
613                 echo $LAST_CRASH_SEC > $OUTDIR/Finished
614                 SEC=$LAST_CRASH_SEC #I used SEC in place of LAST_CRASH_SEC. Here is a quick fix.
615                 #make screenshots
616                 if [ `cat $OUTDIR/$SEC.KEYCODEpure | wc -l` -lt 40 ] # If many keycodes, dont bother trying to make screenshots
617                 then
618                         echo "Making screenschot of $OUTDIR/$SEC.KEYCODEpure"
619                         test -e $OUTDIR/$SEC.KEYCODEpure || echo "DOES NOT EXIST: $OUTDIR/$SEC.KEYCODEpure"
620                         (SCREENSHOT_OUT="auto" ./doNtimes.sh 9 ./reproduce.sh $OUTDIR/$SEC.KEYCODEpure ; echo $f )
621                 fi
622                 mkdirp $OUTDIR/final
623                 mkdirp $OUTDIR/final_cp
624                 #chmod g+w $OUTDIR/final
625                 ln $OUTDIR/$SEC* $OUTDIR/final || cp $OUTDIR/$SEC* $OUTDIR/final
626                 cp $OUTDIR/$SEC* $OUTDIR/final_cp/
627                 cp -rv $OUTDIR/$SEC.replay $OUTDIR/final_cp/
628                 CONFIRM_FILE=`calc_confirm_file`
629                 echo Reproducible > "$CONFIRM_FILE"
630                 
631                 
632                 full_exit
633         fi
634  else
635         do_queued_replays
636  fi
637  do_one_test
638 done
639 kill_all_children $$
640 ) 2>&1 |tee $OUTDIR/log
641 kill_all_children $$
642 }