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