From 81dea0164cd7f36a250a6b4e3619d9471b23fc85 Mon Sep 17 00:00:00 2001 From: Pavel Sanda Date: Sat, 2 Jan 2010 21:46:11 +0000 Subject: [PATCH] New keytest version from John McCabe-Dansted http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg156659.html git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@32740 a592a061-630c-0410-9148-cb99ea01b6c8 --- development/keystest/README | 35 +- development/keystest/add_write_perms.sh | 7 + development/keystest/autolyx | 496 +---------------- development/keystest/doNtimes.sh | 8 +- development/keystest/initXvfb | 26 + development/keystest/keytest.py | 23 +- development/keystest/list_all_children.sh | 2 +- development/keystest/main.sh | 9 + development/keystest/make_screen_shots.sh | 13 + development/keystest/report_html.sh | 186 ++++++- development/keystest/reproduce.sh | 6 + development/keystest/setup.sh | 32 ++ development/keystest/shared_functions.sh | 642 ++++++++++++++++++++++ development/keystest/shared_variables.sh | 3 + development/keystest/view:1 | 3 + development/keystest/watch_keytest.sh | 33 +- 16 files changed, 964 insertions(+), 560 deletions(-) create mode 100755 development/keystest/add_write_perms.sh create mode 100755 development/keystest/initXvfb create mode 100755 development/keystest/main.sh create mode 100755 development/keystest/make_screen_shots.sh create mode 100755 development/keystest/reproduce.sh create mode 100755 development/keystest/setup.sh create mode 100755 development/keystest/shared_functions.sh create mode 100644 development/keystest/shared_variables.sh create mode 100755 development/keystest/view:1 diff --git a/development/keystest/README b/development/keystest/README index e798016b4b..15ee9d44ea 100644 --- a/development/keystest/README +++ b/development/keystest/README @@ -3,40 +3,35 @@ This is a program to spam LyX with millions of randomly generated key presses, and collect the crash results. -Since the code involves spamming random keypresses, I'd recommend -running it in a VM, well away from your main X windows session. +Since the code involves spamming random keypresses, I run it under a special +user "keytest", well away from my main X windows session. -In short, to use this, run development/keytest/lyx_make.sh +To use this software, first configure it by editing the +configuration parameters in shared_functions.sh and shared_variables.sh +then run the following: -It requires the following packages to run - xvkbd wmctrl -the following are also useful: - lyx libqt4-dbg subversion automake +./setup.sh # add keytest user and apt-get required files +sudo -H -u keytest -e xterm # Create a xterm for running keytest in +. ./initXvfb # sets up a fake X server for keytest to play in +./main.sh -It is run by running ./autolyx in one xterm, and ./test.py in another. -I wrote lyx_make.sh as a easy way of updating lyx and running these two -programs together. +Note that this bug finding software is itself quite buggy. CONTENTS: README: this readme file -report.sh: A quick way of generating bug reports and an overview from the logs. +report_html.sh: A quick way of generating bug reports and an overview from the logs. +make_screen_shots.sh: a script for making screenshots, if they are missing from output of above. autolyx: A script to continually restart lyx and collect the bug reports -lyx_make.sh: should updates, compiles, and everything needed to generated logs. maketar.sh: Makes this tar file :) -test.py: Sends LT100 randomly generated keypresses per second to the LyX window. +keytest.py: Sends randomly generated keypresses to the LyX window. killtest: stop the testing stock_text: The stock test to add to each bug report. OUTPUTS: -autolyx: Outputs out/GDB, a log of all output, including backtraces. -test.py: Outputs out/KEYCODES, a list of all keycodes sent to LyX - -reports.sh: Outputs - out/overview: an overview of all the frequency of each error - out/overview_sort: as above but sorted - out/report_*: A collection of autogenerated bug reports. +autolyx: Outputs out/*.GDB, a log of all output, including backtraces. +keytest.py: Outputs out/*.KEYCODES, a list of all keycodes sent to LyX AUTHOR: Copyright (C) 2009 John McCabe-Dansted, gmatht at gmail dot com. diff --git a/development/keystest/add_write_perms.sh b/development/keystest/add_write_perms.sh new file mode 100755 index 0000000000..0438f83975 --- /dev/null +++ b/development/keystest/add_write_perms.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# +# This command makes all files in "$ROOT_OUTDIR" writable by keytest. +# +# This command is useful if you run keytest under a seperate user "keytest" of group "keytest" +. ./shared_variables.sh +find $ROOT_OUTDIR | while read f ; do chmod g+rw $f ; chgrp keytest $f ;done diff --git a/development/keystest/autolyx b/development/keystest/autolyx index bf9f48ad1f..024499251e 100755 --- a/development/keystest/autolyx +++ b/development/keystest/autolyx @@ -1,495 +1,5 @@ #!/bin/bash -# This script starts LyX, and restarts LyX if it is closed -# it logs all output, including backtraces to development/keystest/out/GDB - -#Setting the following may give better screen shots -#gconftool-2 /apps/metacity/general/compositing_manager -s -t bool true - DIRNAME0=`dirname "$0"` -OUTDIR="$DIRNAME0/out" -ROOT_OUTDIR="$DIRNAME0/out" -THIS_PID=$$ - -EXE_TO_TEST=src/lyx - -if [ ! -e "$EXE_TO_TEST" ] -then - echo "$EXE_TO_TEST" does not exist - echo Cannot proceed - exit -fi - -#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 -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 - -LAST_CORE="" - -############################# -# This section of code is LyX Specific -############################# - -if [ ! -e $DIRNAME0/.lyx ] -then - echo WARNING $DIRNAME0/.lyx does not exist - echo will need to regenerate .lyx every test -fi - -#if [ ! -e lib/doc.orig ] -#then -# mv lib/doc lib/doc.orig -#fi - -kill_all_children() { - kill `list_all_children.sh $1` - sleep 0.1 - kill -9 `list_all_children.sh $1` -} - - - -ensure_cannot_print () { -if [ ! -z "$REPLAYFILE" ] -then - return -fi -if lpq -then - - echo We can print, this is bad! - echo use lpadmin to stop keytest from destroying a forest. - full_exit - sleep 999999 ; read -else - echo "Phew, lpq reckons we aren't ready to print. This is a *good* thing!" -fi -} - -extras_save () { - return - for f in `ls lib/doc` - do - if [ lib/doc/$f -nt lib/doc.orig/$f -o ! -e lib/doc.orig/$f ] - then - #echo making doc dir $OUTDIR/$SEC.doc - mkdir -p $OUTDIR/$SEC.doc - cp -a lib/doc/$f $OUTDIR/$SEC.doc/ - fi - done -} - -extras_prepare () { - return - mkdir -p lib/doc/ - rm lib/doc/*.lyx - cp -p lib/doc.orig/*.lyx lib/doc/ -} - -get_crash_id () { - name=`(cat $GDB | grep -o ' in lyx::[[:alnum:]:]*' ; cat $GDB | grep -o ' [ai][nt] [[:alnum:]:]*' ) | head -n3 | sed s/in// | sed 's/ //g'` - echo $name | sed 's/ /__/g' -} - -calc_confirm_file() { - id=`get_crash_id` - echo "$ROOT_OUTDIR/$id.reproduced" -} - -get_pid () { - sleep 3 - echo getting pidof "$1" 1>&2 - #PID=`ps "-u$USER" "$2" | grep "$1" | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'` - PID=`ps x | grep "$1" | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'` - echo "$PID" | ( grep " " > /dev/null && ( echo too many PIDs 1>&2 ; full_exit ) ) - nPIDs=`echo PID "$PID" | wc -l` - echo nPIDs $nPIDs 1>&2 - sleep 1 - echo -- if [ "$nPIDs" != "1" ] 1>&2 - if test "$nPIDs" != "1" #2> /tmp/testerr - then - echo autolyx: Wrong number of PIDs "$nPIDs" "($1)" "($2)" 1>&2 - fi - echo "$PID" - echo got pidof "$1" 1>&2 -} -clean_up () { - KT_PID=`get_pid keytest.py x` - kill $KT_PID - sleep 0.1 - kill -9 $KT_PID -} - -full_exit() { - clean_up - - echo attempting to exit this entire script... normal exit may just exit one function - - kill $THIS_PID - sleep 1 - echo We should not get this far - sleep 1 - kill -9 $THIS_PID - echo We really should not get this far - exit -} - -run_gdb () { - echo Starting GDB - (echo " - shell svn info src/ - run - bt - shell kill $CHILD_PID - shell wmctrl -l - shell sleep 1 - shell kill -9 $CHILD_PID -" ; yes q) | HOME="$NEWHOME" gdb src/lyx 2>&1 | strings| tee $GDB - echo "end run_gdb" - #### gcore $GDB.core - #shell wmctrl -r __renamed__ -b add,shaded - #shell wmctrl -r term -b add,shaded - #shell wmctrl -r term -b add,shaded - #shell wmctrl -R lyx' - # - #shell import -window root '$GDB.png' - #shell import -window root '$GDB..png' - #exit -} - - -########################### - - - -try_replay () { - id=`get_crash_id` - echo CRASH_ID - export CONFIRM_FILE=`calc_confirm_file` - if [ ! -e "$CONFIRM_FILE" ] - then - echo $CONFIRM_FILE does not exist - echo This bug appears not to have been reproduced before - echo Will try to reproduce now - echo - do_replay - echo - echo Finished attempt at replay - else - echo $CONFIRM_FILE exists - echo This bugs has already been reproduced - echo Will not attempt to reproduce again - fi -} - -do_replay() { - (REPLAYFILE="$KEYCODEpure" TAIL_LINES=25 MAX_TAIL_LINES=10000 bash "$0")& - TEST_PID="$!" - echo Backgrounded $TEST_PID - echo waiting for $TEST_PID to finish - wait "$TEST_PID" -} - -test_replayed () { - test -e "$f.replay/last_crash_sec" -o -e "$f.replay/Irreproducible" -} - -move_to_replayed () { - mkdir -p $REPLAY_DIR/replayed - mv $f* $REPLAY_DIR/replayed -} - -do_queued_replays() { -REPLAY_DIR=development/keytest/out/toreplay -for f in `ls $REPLAY_DIR/*KEYCODEpure` -do - if test_replayed - then - move_to_replayed - else - #./development/keytest/killtest - killall lyx - sleep 1 - killall -9 lyx - KEYCODEpure="$f" do_replay - #if test_replayed - #then - move_to_replayed - #fi - fi - -done -} - -#get_pid() { -# ps a | grep $1 | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//' -#} - -do_one_test() { - GDB=$OUTDIR/$SEC.GDB - KEYCODE=$OUTDIR/$SEC.KEYCODE - KEYCODEpure=$OUTDIR/$SEC.KEYCODEpure - NEWHOME=~/kt.dir/$SEC.dir - mkdir -p $NEWHOME - NEWHOME=`cd $NEWHOME; pwd` - echo NEWHOME $NEWHOME - mkdir -p "$NEWHOME" - cp -rv $DIRNAME0/.lyx "$NEWHOME"/ - killall -9 lyx latex pdflatex - ( sleep 9 && - ps a | grep lyx - echo -- 1 || full_exit - LYX_PID="" - i=0 - echo -- while [ -z "$LYX_PID" -a 200 -gt $i ] - while [ -z "$LYX_PID" -a 200 -gt $i ] - do - #export LYX_PID=`ps a | grep /src/lyx | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'` - export LYX_PID=`get_pid "/src/lyx$" ` - echo LYXPID "$LYX_PID" || full_exit - sleep 0.1 - i=$(($i+1)) - done - echo `ps a | grep /src/lyx` - echo -- 2 - echo `ps a | grep /src/lyx | grep -v grep` - echo -- 3 - echo `ps a | grep /src/lyx | grep -v grep | sed 's/ [a-z].*$//'` - echo -- 4 - echo LYX_PID=$LYX_PID - echo XA_PRIMARY | xclip -selection XA_PRIMARY - echo XA_SECONDARY | xclip -selection XA_SECONDARY - echo XA_CLIPBOARD | xclip -selection XA_CLIPBOARD - - echo -- if [ ! -z "$LYX_PID" ] - if [ ! -z "$LYX_PID" ] - then - kill `ps a | grep keytest.py | grep -v grep | cut -c 1-5` - sleep 0.2 - kill -9 `ps a | grep keytest.py | grep -v grep | cut -c 1-5` - while ! wmctrl -r lyx -b add,maximized_vert,maximized_horz - do - echo trying to maximize lyx - sleep 1 - done - KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py | tee $KEYCODE - #echo "$!" > $NEWHOME/keytest_py.pid - fi - killall lyx) & - CHILD_PID="$!" - ls src/lyx ; sleep 1 - pwd - - #You may want to use the following to simulate SIGFPE - #(sleep 90 && killall -8 lyx) & - echo TTL $TAIL_LINES - extras_prepare - ensure_cannot_print - run_gdb -# (run_gdb) & -# GDBTASK_PID="$!" -# (sleep 600 ; kill "$!") -# echo WAITING FOR: wait $GDBTASK_PID -# wait $GDBTASK_PID -# echo NOLONGER waiting for: wait $GDBTASK_PID - - echo END gdb - kill $CHILD_PID - KT_PID=`get_pid keytest.py` - echo KT_PID=$KT_PID - kill $KT_PID - sleep 0.3 - kill -9 $CHILD_PID - kill -9 $KT_PID - # Or use "exited normally": - echo END gdb2 - # these tend to take up a huge amount of space: - rm -rf $NEWHOME - if (grep " signal SIG[^TK]" $GDB || grep KILL_FREEZE $KEYCODE) - then - extras_save - mkdir -p $OUTDIR/save && ( - ln $OUTDIR/$SEC.* $OUTDIR/save || - cp $OUTDIR/$SEC.* $OUTDIR/save) - LAST_CRASH_SEC=$SEC - echo $LAST_CRASH_SEC > $OUTDIR/last_crash_sec - if [ ! -z "$TAIL_LINES" ] - then - LAST_EVENT="$SEC" - echo Reproducible > $OUTDIR/Reproducible - fi - TAIL_LINES="" - if [ -z "$REPLAYFILE" ] - then - echo ATTEMPTING TO REPLAY - try_replay - else - export KEYTEST_INFILE=$KEYCODEpure - NUM_KEYCODES=`wc -l < $KEYCODEpure` - echo NUM_KEYCODES $NUM_KEYCODES, was $LAST_NUM_KEYCODES - if [ "$NUM_KEYCODES" != "$LAST_NUM_KEYCODES" ] - then - LAST_EVENT="$SEC" - LAST_NUM_KEYCODES=$NUM_KEYCODES - echo "Hooray! we have eleminated some keycodes" - fi - fi - if [ ! -z "$AND_THEN_QUIT" ] - then - RESULT=1 - echo RR 1 - return 1 - fi - if [ ! -z "$LAST_CORE" ] - then - rm "$LAST_CORE" - fi - LAST_CORE="$GDB.core" - else - rm -rf $BAK/* - mv $OUTDIR/$SEC.* $BAK/ - if [ ! -z "$TAIL_LINES" ] - then - echo TTL3 $TAIL_LINES - echo MAX_TAIL_LINES "$MAX_TAIL_LINES" - TAIL_LINES=$(($TAIL_LINES*2)) - echo TTL4 $TAIL_LINES - if [ "$TAIL_LINES" -ge "0$MAX_TAIL_LINES" -a ! -z "$MAX_TAIL_LINES" ] - then - echo Giving up because $TAIL_LINES '>' $MAX_TAIL_LINES - echo Irreproducible > $OUTDIR/Irreproducible - full_exit - fi - fi - if [ ! -z "$AND_THEN_QUIT" ] - then - RESULT=0 - echo RR 0 - return 0 - fi - - echo TTL2 $TAIL_LINES - fi -} - -if [ ! -z "$1" ] -then - REPLAYFILE=$1 -fi - -if [ ! -z "$REPLAYFILE" ] -then - echo REPLAYMODE - OUTDIR="$REPLAYFILE.replay/" - mkdir -p $REPLAYFILE.replay/ || full_exit - export KEYTEST_INFILE=$REPLAYFILE - if [ ! -e "$REPLAYFILE" ] - then - echo "$REPLAYFILE" does not exist - echo exiting - full_exit 1 - fi -else - do_queued_replays - echo RANDOM MODE -fi - -get_pid [0-9].x-session-manager"$" x -export X_PID=`get_pid [0-9].x-session-manager x` -echo X_PID $X_PID - -export TAIL_LINES=$TAIL_LINES -echo TL $TAIL_LINES - - -BAK="$OUTDIR/backup" -mkdir -p $BAK - - - - -#rename other windows to avoid confusion. -wmctrl -N __renamed__ -r lyx -wmctrl -N __renamed__ -r lyx -wmctrl -N __renamed__ -r lyx -wmctrl -N __renamed__ -r lyx -export PATH=`cd $DIRNAME0; pwd`/path:$PATH - -if [ ! -z "$1" ] -then - SEC=`date +%s` - export MAX_DROP=0 - if [ ".$SCREENSHOT_OUT." = ".auto." ] - then - echo SCREENSHOT_OUT was $SCREENSHOT_OUT. - export SCREENSHOT_OUT="$OUTDIR/$SEC.s" - echo SCREENSHOT_OUT is $SCREENSHOT_OUT. - #exit - fi - export RESULT=179 - do_one_test #| tee do_one_test.log - RESULT="$?" - echo Ressult $RESULT - - kill `list_all_children.sh $$` - sleep 0.1 - kill -9 `list_all_children.sh $$` - - exit $RESULT - - #echo done ; sleep 1 - full_exit -fi - - - -( -echo TTL $TAIL_LINES - -LAST_EVENT=`date +%s` # Last time something interesting happened. If nothing interesting has happened for a while, we should quit. - -ensure_cannot_print -echo X_PID $X_PID -export X_PID=`get_pid [0-9].x-session-manager"$" x` -echo PATH $PATH -while true -do - echo Currently running autolyx PID=$$ - if [ ! -z "$TAIL_LINES" ] - then - echo TAIL_LINES: "$TAIL_LINES" - TAIL_FILE=$OUTDIR/tail_"$TAIL_LINES" - tail -n "$TAIL_LINES" "$REPLAYFILE" > $TAIL_FILE - KEYTEST_INFILE=$TAIL_FILE - MAX_DROP=0 - else - MAX_DROP=0.2 - fi - export MAX_DROP - SEC=`date +%s` - if [ ! -z "$REPLAYFILE" ] - then - echo Boredom factor: $SEC-$LAST_EVENT'=' $(($SEC-$LAST_EVENT)) - if [ $(($SEC-$LAST_EVENT)) -gt $BORED_AFTER_SECS ] - then - echo - echo Is is now $SEC seconds - echo The last time we managed to eliminate a keycode was at $LAST_EVENT - echo We get bored after $BORED_AFTER_SECS seconds - echo Giving up now. - echo - echo $LAST_CRASH_SEC > $OUTDIR/Finished - mkdir $OUTDIR/final - ln $OUTDIR/$SEC* $OUTDIR/final || cp $OUTDIR/$SEC* $OUTDIR/final - CONFIRM_FILE=`calc_confirm_file` - echo Reproducible > "$CONFIRM_FILE" - - - full_exit - fi - else - do_queued_replays - fi - do_one_test -done -kill_all_children $$ -) 2>&1 |tee $OUTDIR/log -kill_all_children $$ +. $DIRNAME0/shared_variables.sh +. $DIRNAME0/shared_functions.sh +autolyx_main "$@" diff --git a/development/keystest/doNtimes.sh b/development/keystest/doNtimes.sh index 0ea176d7cb..f647d6440e 100755 --- a/development/keystest/doNtimes.sh +++ b/development/keystest/doNtimes.sh @@ -1,5 +1,8 @@ #!/bin/bash -KT=`dirname $0` +KT=`dirname "$0"` + +. "$KT/shared_functions.sh" + N=$1 shift @@ -13,8 +16,11 @@ do if ! "$@" then echo TRIES_REQUIRED: $i + kill_all_children $$ exit 1 fi done +kill_all_children $$ echo DONE $N TIMES + diff --git a/development/keystest/initXvfb b/development/keystest/initXvfb new file mode 100755 index 0000000000..ed1e6d1137 --- /dev/null +++ b/development/keystest/initXvfb @@ -0,0 +1,26 @@ +if [ -z "$1" ] +then + d=1 +else + d=$1 +fi + +#Xvfb :1 -screen 1 800x600x24 -fbdir /tmp & +#Xvfb :1 -screen 1 800x600x24 -pixdepths "1 8 16 24 32" & +#Xvfb :$d -ac -screen 0 800x600x24 -wr +echo 1 +Xvfb :$d -ac -screen 0 800x600x24 -wr & + +echo 2 +export DISPLAY=:$d +echo 3 +icewm& +echo 4 +#metacity& +echo 5 +while true +do + sleep 300 + icewm & +done & +echo 6 diff --git a/development/keystest/keytest.py b/development/keystest/keytest.py index 4bbe3ce218..663714d38b 100755 --- a/development/keystest/keytest.py +++ b/development/keystest/keytest.py @@ -137,6 +137,8 @@ class CommandSourceFromFile(CommandSource): os._exit(0) if self.i >= len(self.lines): self.loops = self.loops + 1 + if self.loops > 3: + os._exit(0) self.i = 0 return 'Loop' line = self.lines[self.i] @@ -181,18 +183,31 @@ def sendKeystring(keystr, LYX_PID): while not lyx_sleeping(): time.sleep(0.02) print '.', - print 'Making Screenshot: ' + screenshot_out + print 'Making Screenshot: ' + screenshot_out + ' OF ' + infilename time.sleep(0.2) os.system('import -window root '+screenshot_out+str(x.count)+".png") time.sleep(0.1) sys.stdout.flush() subprocess.call(["xvkbd", "-xsendevent", "-delay", DELAY, "-text", keystr]) +def system_retry(num_retry, cmd): + i = 0 + rtn = os.system(cmd) + while ( ( i < num_retry ) and ( rtn != 0) ): + i = i + 1 + rtn=os.system(cmd) + time.sleep(1) + if ( rtn != 0 ): + print "Command Failed: "+cmd + print " EXITING!\n" + os._exit(1) + def RaiseWindow(): os.system("echo x-session-manager PID: $X_PID.") os.system("echo x-session-manager open files: `lsof -p $X_PID | grep ICE-unix | wc -l`") - os.system("wmctrl -l | ( grep '"+lyx_window_name+"' || ( killall lyx ; sleep 1 ; killall -9 lyx ))") - os.system("wmctrl -R '"+lyx_window_name+"' ;sleep 0.1") + ####os.system("wmctrl -l | ( grep '"+lyx_window_name+"' || ( killall lyx ; sleep 1 ; killall -9 lyx ))") + #os.system("wmctrl -R '"+lyx_window_name+"' ;sleep 0.1") + system_retry(30, "wmctrl -R '"+lyx_window_name+"'") lyx_pid = os.environ.get('LYX_PID') @@ -253,7 +268,7 @@ while True: if os.path.exists('/proc/' + lyx_pid + '/status'): sendKeystring(c[4:], lyx_pid) else: - os.system('killall lyx; sleep 2 ; killall -9 lyx') + ##os.system('killall lyx; sleep 2 ; killall -9 lyx') print 'No path /proc/' + lyx_pid + '/status, exiting' os._exit(1) elif c[0:4] == 'KD: ': diff --git a/development/keystest/list_all_children.sh b/development/keystest/list_all_children.sh index 11359aed64..b6b012ceb1 100755 --- a/development/keystest/list_all_children.sh +++ b/development/keystest/list_all_children.sh @@ -18,7 +18,7 @@ kill_all_children () { kill -9 `listall "$*"` } -if [ "$1"="$kill" ] +if [ "$1" = "kill" ] then shift kill_all_children "$*" diff --git a/development/keystest/main.sh b/development/keystest/main.sh new file mode 100755 index 0000000000..367d9fd707 --- /dev/null +++ b/development/keystest/main.sh @@ -0,0 +1,9 @@ +#PWD=`pwd` +if [ "$USER" != keytest ] +then + echo USER is "$USER", not keytest! Exiting. + exit +fi +#(DISPLAY=:1 sudo -u keytest -H nice -18 ; cd $PWD ; ./autolyx) +./killtest.sh # kill any previous test, so does not interfere +./autolyx diff --git a/development/keystest/make_screen_shots.sh b/development/keystest/make_screen_shots.sh new file mode 100755 index 0000000000..5d979b6792 --- /dev/null +++ b/development/keystest/make_screen_shots.sh @@ -0,0 +1,13 @@ +. ./shared_variables.sh +OUT=$ROOT_OUTDIR +for f in `ls $OUT/*/final/*pure` +do +echo file_ $f +if [ ! -e $f.replay ] +then + echo replaying $f for screenshot + #(SCREENSHOT_OUT="auto" ./doNtimes.sh 3 ./reproduce.sh $f ; echo $f ; ./list_all_children.sh kill $$ ) 2>&1 | tee $f.screenshot-log + (SCREENSHOT_OUT="auto" ./doNtimes.sh 9 ./reproduce.sh $f ; echo $f ) 2>&1 | tee $f.screenshot-log + echo replayed $f for screenshot +fi +done diff --git a/development/keystest/report_html.sh b/development/keystest/report_html.sh index 0940c0606d..6f9c85bce9 100755 --- a/development/keystest/report_html.sh +++ b/development/keystest/report_html.sh @@ -1,31 +1,45 @@ #!/bin/bash #LT=development/keystest LT=`dirname $0` +. $LT/shared_variables.sh GEOM=320x200 QUALITY=85 if [ -z "$KEYCODE_DIR" ] then - KEYCODE_DIR=out + KEYCODE_DIR=$ROOT_OUTDIR fi #convert -normalize -scale $GEOM -quality $QUALITY $f $GEOM/$f UNIQUE_LINE=1 -OUT=$LT/out/html4 +OUT=$LT/$OUT_NAME/html +URL_OF_OUT=http://gmatht.homelinux.net/xp/$OUT_NAME/html/ mkdir -p $OUT rm $OUT/index*.html ls $OUT/*.html CPP_HTML_DIR_REL=cpp_html -CPP_HTML_DIR=$out/cpp_html +CPP_HTML_DIR=$OUT/cpp_html -strings $LT/out/GDB.* > $LT/out/GDBs -grep "#$UNIQUE_LINE " $LT/out/GDBs > $LT/out/list -cat $LT/out/list | sed 's/0x[^ )]*[ )]/.*/g' | sort | uniq | tee $LT/out/listuniq +LYX_VER=`src/lyx -version 2>&1 | head -n1 | sed s/^LyX\ // | sed s/\ .*// | sed s/1svn/0/ | sed s/2svn/1/ | sed s/3svn/2/ | sed s/4svn/3/ | sed s/5svn/4/ | sed s/6svn/5/ | sed s/7svn/6/ | sed s/8svn/7/ | sed s/9svn/8/` +BOILER_PLATE=`cd src ; svn info 2>&1 | grep Revision` + +strings $LT/$OUT_NAME/GDB.* > $LT/$OUT_NAME/GDBs +grep "#$UNIQUE_LINE " $LT/$OUT_NAME/GDBs > $LT/$OUT_NAME/list +cat $LT/$OUT_NAME/list | sed 's/0x[^ )]*[ )]/.*/g' | sort | uniq | tee $LT/$OUT_NAME/listuniq echo '' >> $OUT/indexreport.html +list_keycode_files () { +echo for f in $OUT_NAME/*y/last_crash_sec $OUT_NAME/toreplay/replayed/*y/last_crash_sec +for f in $OUT_NAME/*y/last_crash_sec $OUT_NAME/toreplay/replayed/*y/last_crash_sec $OUT_NAME/toreplay/*y/last_crash_sec $OUT_NAME/toreplay/final/*y/last_crash_sec +do + keycode_file=$(echo $f | sed s/last_crash_sec/$(cat $f).KEYCODEpure/) + echo $keycode_file +done +} + tidy_keycode () { while read -r k do @@ -49,9 +63,62 @@ html_keycode() { } + +trac_keycode() { + echo -n "'''" + cat "$f_base.KEYCODEpure" | tidy_keycode + echo -n "'''" + #echo -n '""' + #echo -n '' + cat "$f_base.KEYCODEpure+" | tidy_keycode + #echo -n '' + +} + +line2url() { + echo "$@" | sed 's/&/%26/g' | sed 's/"/%22/g' | sed 's/#/%23/g' | sed 's/;/%3B/g' +} + +text2url() { + #echo "$@" | + while read -r L + do + #echo -n `echo "$L" | line2url`'%0A' + echo -n `line2url "$L"`'%0A' + done +} + +report_bug_url () { + #http://www.lyx.org/trac/newticket?description=bar%0Abar2&summary=foo%13oo&keywords=crash&version=1.6.5 + #http://www.lyx.org/trac/newticket?summary=foo%13oo&description=bar%0Abar2&version=1.6.5&keywords=crash + #ver=`echo $3 | sed s/1svn/0/ | sed s/2svn/1/ | sed s/3svn/2/ | sed s/4svn/3/ | sed s/5svn/4/ | sed s/6svn/5/ | sed s/7svn/6/ | sed s/8svn/7/ | sed s/9svn/8/` + #echo 'http://www.lyx.org/trac/newticket?summary='`line2url "$1"`'&description='`text2url "$2"`'&version='"$LYX_VER"'&keywords=crash' + DESC=`get_description | text2url` + #DESC=`text2url "$DESC"` + if echo $DESC | grep SIGSEGV > /dev/null + then + KEYWORDSTR="&keywords=crash" + else + if echo $DESC | grep SIGABRT > /dev/null + then + KEYWORDSTR="&keywords=assertion" + elif echo $DESC | grep SIGSEGV > /dev/null + then + KEYWORDSTR="crash" + fi + fi + echo 'http://www.lyx.org/trac/newticket?summary='`line2url "$TITLE"`"&description=$DESC&version=$LYX_VER$KEYWORDSTR" + #echo 'http://www.lyx.org/trac/newticket?description='"$1"'&summary=foo%13oo&keywords=crash&version=1.6. +} + +search_bug_url () { + #http://www.lyx.org/trac/search?q=Foo%20bar + echo 'http://www.lyx.org/trac/search?q='`line2url "$TITLE"` +} + gdb2html() { -echo g $g -cat $g | sed 's/&/&/g' | sed 's/' +head $g -n 100 | sed 's/&/\&/g' | sed 's//' } +get_description() { + echo "Keycodes: " + trac_keycode + ii=1 + echo + echo To reproduce: + cat "$f_base.KEYCODEpure" "$f_base.KEYCODEpure+" | while read -r L + do + echo "$ii) ... ($L)" + ii=$((ii+1)) + done + + echo + echo Arch: `arch` + svn_revision $f_base + echo '{{{' + cat $g + echo '}}}' + echo + echo For more info see the "[[$URL_OF_OUT/$HTML_NAME Keytest Report]]" +} + +make_cpp_html() { +#This is ugly. At the moment all bug reports in the same set reference the same files, which could lead to confusion if they are from differnt versions of lyx. Do not mix different versions until this is fixed. However we may not want to "fix" this when it may be better to always use a new outdir for each version and just reproduce the old bugs so they don't get lost. +if ! test -e $ROOT_OUTDIR/html/cpp_html +then + (mkdir -p $ROOT_OUTDIR/html/cpp_html/ && + cd $ROOT_OUTDIR/html/cpp_html/ && + for f in `f ../../../src/ .cpp$` ; do g=`basename $f`; c2html -n < $f > $g.html ; echo $f ; done) +fi +} + +svn_revision() { +#| grep ^Revision | sed s/'Revision: '/r/ +echo KEYCODE $1 ... `dirname $1` 1>&2 +cat `dirname $1`/last_crash_sec.info.svn | grep ^Revision +echo _KEYCODE $KEYCODE ... 1>&2 +} + + + + echo beginning -#for file in `find $LT/out/ -anewer $LT/out/html | grep replay/last_crash_sec` +make_cpp_html +#for file in `find $LT/$OUT_NAME/ -anewer $LT/$OUT_NAME/html | grep replay/last_crash_sec` #for file in `find $KEYCODE_DIR | grep save/.*KEYCODEpure` -for file in `find $KEYCODE_DIR -anewer oldfile | grep save/.*KEYCODEpure$` +#for file in `find $KEYCODE_DIR -anewer oldfile | grep save/.*KEYCODEpure$ | head -n4` +#for file in `ls $KEYCODE_DIR/*/final/*KEYCODEpure` +#for file in `ls $KEYCODE_DIR/*/final/*/*KEYCODEpure` +list_keycode_files +echo END OF KEYCODE FILES +for file in `list_keycode_files` do + echo FILE $file lcs_file=`echo $file | sed 's/save\/.*//g'`last_crash_sec echo last_crash_sec file: $lcs_file SEC2=`cat $lcs_file` @@ -99,7 +215,7 @@ do echo f_base $f_base NUM_KEYCODES=`wc -l < "$f_base.KEYCODEpure"` echo NUM_KEYCODES=$NUM_KEYCODES... - if [ "$NUM_KEYCODES" -lt 80 ] + if [ "$NUM_KEYCODES" -lt 10 ] then echo f_base $f_base f=$f_base.GDB @@ -113,29 +229,47 @@ do TITLE="$SIGNAL $IN_AT" TITLE_=`echo $TITLE|sed s/[^[:alnum:]]/_/g` INDEX="index.html" + HTML_NAME=$SEC.html # name of html report for this bug echo TITLE $TITLE echo INDEX $INDEX echo NEW $INDEX - echo '' >> $LT/out/$INDEX - echo -n "$TITLE " >> $OUT/indexreport.html - html_keycode >> $OUT/indexreport.html - if ls $f_base.s*.png - then - echo -n "screenshots" >> $OUT/indexreport.html - fi - echo -n '
'>> $OUT/indexreport.html - echo >> $OUT/indexreport.html - echo -n '
'>> $LT/out/$INDEX - echo >> $LT/out/$INDEX + echo '' >> $LT/$OUT_NAME/$INDEX + (echo -n "
$TITLE " + html_keycode + echo " [search] [report] screenshots" + #if ls $f_base.s*.png + #then + # echo "screenshots" + #fi + #echo -n '
' + echo ) >> $OUT/indexreport.html + echo -n '
'>> $LT/$OUT_NAME/$INDEX + echo >> $LT/$OUT_NAME/$INDEX ( echo '' - echo "

$TITLE

" + echo "$TITLE" html_keycode - echo "KEYCODES " + echo "
KEYCODES " + echo " pure " echo "GDB" + if ls $f_base.s*.png > /dev/null + then + echo "screenshots" + else + echo '(no screenshots)' + fi + echo "
" + + #echo -n '
' + #echo "

" - echo "

" + #echo "

" gdb2html + (echo ---- + svn_revision $f_base + echo arch `arch` + dpkg -l | egrep '(libqt4-dbg|libc6 |libboost-dev )' + lsb_release -a) | sed 's/&/\&/g' | sed 's//' ) > $OUT/$SEC.html echo ''$SEC'
' >> $OUT/$INDEX echo ''$SEC'
' @@ -155,6 +289,8 @@ done mv $OUT/indexreport.html $OUT/indexreport.html.bak echo "" >> $OUT/indexreport.html echo "

List of bugs found

" >> $OUT/indexreport.html +echo '

Please, do not "report" bugs without searching for them first. Also make sure to fill out the "To reproduce" section before pressing the "Create ticket" button

' >> $OUT/indexreport.html sort -k 2 -t '>' < $OUT/indexreport.html.bak >> $OUT/indexreport.html firefox $OUT/indexreport.html +#google-chrome $OUT/indexreport.html diff --git a/development/keystest/reproduce.sh b/development/keystest/reproduce.sh new file mode 100755 index 0000000000..e2421245fe --- /dev/null +++ b/development/keystest/reproduce.sh @@ -0,0 +1,6 @@ +#!/bin/bash +KT=`dirname $0` +AND_THEN_QUIT="y" time $KT/autolyx $1 +RESULT=$? +echo RESULT_REPRODUCE $RESULT +exit $RESULT diff --git a/development/keystest/setup.sh b/development/keystest/setup.sh new file mode 100755 index 0000000000..9b38777774 --- /dev/null +++ b/development/keystest/setup.sh @@ -0,0 +1,32 @@ + +#This won't work on an RPM based distro. Easy to fix though. +sudo apt-get install xclip xvkbd wmctrl xvfb libqt4-dbg icewm #svn pylint +sudo adduser keytest < /dev/null + +if ! grep keytest /etc/sudoers +then + echo allowing admin users to switch to keytest user + #echo '%adm ALL =(keytest) NOPASSWD: ALL' >> /etc/sudoers +fi +# cat /mnt/jaunty/etc/cups/printers.conf |grep -o '[^ ]*>$' |grep -v '^<'| sed 's/>$//' + +#we should really handle each printer seperately, but this will work if they are similar +if grep AllowUser /etc/cups/printers.conf +then + echo printer: using whitelisting, nothings needs be done. + exit +fi + +if grep DenyUser /etc/cups/printers.conf +then + echo There are already denied users. We do not support this yet, exiting + exit +fi + +#(cd /etc/cups/ppd/ && ls *.ppd) | sed s/.ppd$// | while read L +cat /etc/cups/printers.conf |grep -o '[^ ]*>$' |grep -v '^<'| sed 's/>$//' | while read L +do + echo $L + echo lpadmin -p $L -u deny:keytest + lpadmin -p $L -u deny:keytest +done diff --git a/development/keystest/shared_functions.sh b/development/keystest/shared_functions.sh new file mode 100755 index 0000000000..d7cd4ba947 --- /dev/null +++ b/development/keystest/shared_functions.sh @@ -0,0 +1,642 @@ +DIRNAME0=`dirname "$0"` +#ROOT_OUTDIR="$DIRNAME0/out" +OUTDIR="$ROOT_OUTDIR" +#OUTDIR="$DIRNAME0/out" +THIS_PID=$$ + +SRC_DIR=lyx/src +EXE_TO_TEST=$SRC_DIR/lyx + +#kill(){ +# echo kill +#} +#killall (){ +# echo killall +#} + +mkdirp () { + mkdir -p "$1" + chmod g+w "$1" +} + +kill_all_children() { + kill `$DIRNAME0/list_all_children.sh $1` + sleep 0.1 + kill -9 `$DIRNAME0/list_all_children.sh $1` +} + + +#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 +if [ -z $BORED_AFTER_SECS ] +then + 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 +fi + +LAST_CORE="" + +############################# +# This section of code is LyX Specific +############################# + +if [ ! -e $DIRNAME0/.lyx ] +then + echo WARNING $DIRNAME0/.lyx does not exist + echo will need to regenerate .lyx every test +fi + +#if [ ! -e lib/doc.orig ] +#then +# mv lib/doc lib/doc.orig +#fi + +#kill_all_children() { +# kill `$DIRNAME0/list_all_children.sh $1` +# sleep 0.1 +# kill -9 `$DIRNAME0/list_all_children.sh $1` +#} + +#. $DIRNAME0/shared_functions.sh + + +ensure_cannot_print () { +if [ ! -z "$REPLAYFILE" ] +then + return +fi +if lpq +then + + echo We can print, this is bad! + echo use lpadmin to stop keytest from destroying a forest. + full_exit + sleep 999999 ; read +else + echo "Phew, lpq reckons we aren't ready to print. This is a *good* thing!" +fi +} + +extras_save () { + return + for f in `ls lib/doc` + do + if [ lib/doc/$f -nt lib/doc.orig/$f -o ! -e lib/doc.orig/$f ] + then + #echo making doc dir $OUTDIR/$SEC.doc + mkdirp $OUTDIR/$SEC.doc + cp -a lib/doc/$f $OUTDIR/$SEC.doc/ + fi + done +} + +extras_prepare () { + return + mkdirp lib/doc/ + rm lib/doc/*.lyx + cp -p lib/doc.orig/*.lyx lib/doc/ +} + +get_crash_id () { + name=`(cat $GDB | grep -o ' in lyx::[[:alnum:]:]*' ; cat $GDB | grep -o ' [ai][nt] [[:alnum:]:]*' ) | head -n3 | sed s/in// | sed 's/ //g'` + echo $name | sed 's/ /__/g' +} + +calc_confirm_file() { + id=`get_crash_id` + echo "$ROOT_OUTDIR/$id.reproduced" +} + +get_pid () { + sleep 3 + echo getting pidof "$1" 1>&2 + #PID=`ps "-u$USER" "$2" | grep "$1" | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'` + PID=`ps x | grep "$1" | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'` + echo "$PID" | ( grep " " > /dev/null && ( echo ERROR too many PIDs 1>&2 ; ps x ; full_exit ) ) + nPIDs=`echo PID "$PID" | wc -l` + echo nPIDs $nPIDs 1>&2 + sleep 1 + echo -- if [ "$nPIDs" != "1" ] 1>&2 + if test "$nPIDs" != "1" #2> /tmp/testerr + then + echo autolyx: Wrong number of PIDs "$nPIDs" "($1)" "($2)" 1>&2 + echo autolyx: PIDs "$PID" 1>&2 + ps x 1>&2 + echo ----- + fi + echo "$PID" + echo got pidof "$1" 1>&2 +} +clean_up () { + KT_PID=`get_pid keytest.py x` + kill $KT_PID + sleep 0.1 + kill -9 $KT_PID +} + +full_exit() { + clean_up + + echo attempting to exit this entire script... normal exit may just exit one function + + kill $THIS_PID + sleep 1 + echo We should not get this far + sleep 1 + kill -9 $THIS_PID + echo We really should not get this far + exit +} + +run_gdb () { + #Spawn a process to kill lyx if it runs too long + if ! touch $GDB + then + echo cannot touch $GDB + full_exit + fi + (sleep 300; echo KILLER ACTIVATIED ;killall gdb lyx ; sleep 1 ; killall -9 gdb lyx)& + KILLER_PID=$! + echo KILLING LYX, before starting new lyx + killall lyx + sleep 1 + killall lyx -9 + sleep 1 + echo Starting GDB + #shell svn info $SRC_DIR/ + (echo " + run + bt + #shell kill $CHILD_PID + shell wmctrl -l + #shell sleep 1 + #shell kill -9 $CHILD_PID +" ; yes q) | HOME="$NEWHOME" gdb $EXE_TO_TEST 2>&1 | strings| tee $GDB + echo "end run_gdb ($KILLER_PID)" + kill $KILLER_PID + sleep 0.1 + kill -9 $KILLER_PID + + #### gcore $GDB.core + #shell wmctrl -r __renamed__ -b add,shaded + #shell wmctrl -r term -b add,shaded + #shell wmctrl -r term -b add,shaded + #shell wmctrl -R lyx' + # + #shell import -window root '$GDB.png' + #shell import -window root '$GDB..png' + #exit +} + + +########################### + + + +try_replay () { + id=`get_crash_id` + echo CRASH_ID + export CONFIRM_FILE=`calc_confirm_file` + if [ ! -e "$CONFIRM_FILE" ] + then + echo $CONFIRM_FILE does not exist + echo This bug appears not to have been reproduced before + echo Will try to reproduce now + echo + do_replay + echo + echo Finished attempt at replay + else + echo $CONFIRM_FILE exists + echo This bugs has already been reproduced + echo Will not attempt to reproduce again + fi +} + +do_replay() { + (REPLAYFILE="$KEYCODEpure" TAIL_LINES=25 MAX_TAIL_LINES=10000 bash "$0")& + TEST_PID="$!" + echo Backgrounded $TEST_PID + echo waiting for $TEST_PID to finish + wait "$TEST_PID" +} + +test_replayed () { + test -e "$f.replay/last_crash_sec" -o -e "$f.replay/Irreproducible" +} + +move_to_replayed () { + mkdirp $REPLAY_DIR/replayed + mv $f* $REPLAY_DIR/replayed +} + +do_queued_replay() { + if test_replayed + then + move_to_replayed + else + #./development/keytest/killtest + killall lyx + sleep 1 + echo killall -9 lyx + killall -9 lyx + KEYCODEpure="$f" do_replay + #if test_replayed + #then + move_to_replayed + #fi + fi +} + +do_queued_replays() { +REPLAY_DIR=$OUTDIR/toreplay +echo doing queued_replays +echo replays `ls $REPLAY_DIR/*KEYCODEpure` +for f in `ls $REPLAY_DIR/*KEYCODEpure` +do + do_queued_replay +done +echo done queued_replays +( + REPLAY_DIR=$OUTDIR/toreproduce + export BORED_AFTER_SECS=0 + echo doing queued_reproduce + echo reproduce`ls $REPLAY_DIR/*KEYCODEpure` + for f in `ls $REPLAY_DIR/*KEYCODEpure` + do + do_queued_replay + done + echo done queued_reproduce +) +} + +#get_pid() { +# ps a | grep $1 | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//' +#} + +get_version_info() { + (cd $SRC_DIR ; svn info) 2>&1 |tee "$1".svn + $EXE_TO_TEST -version 2>&1 "$1".version +} + +do_one_test() { + GDB=$OUTDIR/$SEC.GDB + KEYCODE=$OUTDIR/$SEC.KEYCODE + KEYCODEpure=$OUTDIR/$SEC.KEYCODEpure + NEWHOME=~/kt.dir/$SEC.dir + mkdirp $NEWHOME + NEWHOME=`cd $NEWHOME; pwd` + echo NEWHOME $NEWHOME + mkdirp "$NEWHOME" + cp -rv $DIRNAME0/.lyx "$NEWHOME"/ + echo killall -9 lyx latex pdflatex + killall -9 lyx latex pdflatex + ( sleep 9 && + ps a | grep lyx + echo -- 1 || full_exit + LYX_PID="" + i=0 + echo -- while [ -z "$LYX_PID" -a 200 -gt $i ] + while [ -z "$LYX_PID" -a 200 -gt $i ] + do + #export LYX_PID=`ps a | grep /src/lyx | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'` + export LYX_PID=`get_pid "$EXE_TO_TEST$" ` + echo LYXPID "$LYX_PID" || full_exit + sleep 0.1 + i=$(($i+1)) + done + echo `ps a | grep $EXE_TO_TEST` + echo -- 2 + echo `ps a | grep $EXE_TO_TEST | grep -v grep` + echo -- 3 + echo `ps a | grep $EXE_TO_TEST | grep -v grep | sed 's/ [a-z].*$//'` + echo -- 4 + echo LYX_PID=$LYX_PID + echo XA_PRIMARY | xclip -selection XA_PRIMARY + echo XA_SECONDARY | xclip -selection XA_SECONDARY + echo XA_CLIPBOARD | xclip -selection XA_CLIPBOARD + + echo -- if [ ! -z "$LYX_PID" ] + if [ ! -z "$LYX_PID" ] + then + kill `ps a | grep keytest.py | grep -v grep | cut -c 1-5` + sleep 0.2 + kill -9 `ps a | grep keytest.py | grep -v grep | cut -c 1-5` + while ! wmctrl -r lyx -b add,maximized_vert,maximized_horz + do + echo trying to maximize lyx + sleep 1 + done + echo BEGIN KEYTEST KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py + KEYTEST_OUTFILE="$KEYCODEpure" nice -19 python $DIRNAME0/keytest.py | tee $KEYCODE + #echo "$!" > $NEWHOME/keytest_py.pid + echo END_KEYTEST + fi + echo NO_KEYTEST + echo killall lyx + killall lyx + sleep 0.1 + kill -9 "$LYX_PID" + killall -9 lyx #sometimes LyX really doesn't want to die causing the script to freeze + #killall lyx #sometimes LyX really doesn't want to die causing the script to freeze + sleep 1 + #kill -9 "$LYX_PID" #sometimes LyX really doesn't want to die causing the script to freeze + + #sleep 1 + #killall -9 lyx + ) & + CHILD_PID="$!" + ls $EXE_TO_TEST ; sleep 1 + pwd + + #You may want to use the following to simulate SIGFPE + #(sleep 90 && killall -8 lyx) & + echo TTL $TAIL_LINES + extras_prepare + ensure_cannot_print + run_gdb +# (run_gdb) & +# GDBTASK_PID="$!" +# (sleep 600 ; kill "$!") +# echo WAITING FOR: wait $GDBTASK_PID +# wait $GDBTASK_PID +# echo NOLONGER waiting for: wait $GDBTASK_PID + + echo END gdb + kill $CHILD_PID + KT_PID=`get_pid keytest.py` + echo KT_PID=$KT_PID + kill $KT_PID + sleep 0.3 + kill -9 $CHILD_PID + kill -9 $KT_PID + # Or use "exited normally": + echo END gdb2 + # these tend to take up a huge amount of space: + echo will erase "$NEWHOME" + sleep 2 + rm -rf $NEWHOME + if (grep " signal SIG[^TK]" $GDB || grep KILL_FREEZE $KEYCODE) + then + extras_save + mkdirp $OUTDIR/save && ( + ln $OUTDIR/$SEC.* $OUTDIR/save || + cp $OUTDIR/$SEC.* $OUTDIR/save) + LAST_CRASH_SEC=$SEC + echo $LAST_CRASH_SEC > $OUTDIR/last_crash_sec + get_version_info $OUTDIR/last_crash_sec.info + if [ ! -z "$TAIL_LINES" ] + then + LAST_EVENT="$SEC" + echo Reproducible > $OUTDIR/Reproducible + fi + TAIL_LINES="" + if [ -z "$REPLAYFILE" ] + then + echo ATTEMPTING TO REPLAY + try_replay + else + export KEYTEST_INFILE=$KEYCODEpure + NUM_KEYCODES=`wc -l < $KEYCODEpure` + echo NUM_KEYCODES $NUM_KEYCODES, was $LAST_NUM_KEYCODES + if [ "$NUM_KEYCODES" != "$LAST_NUM_KEYCODES" ] + then + LAST_EVENT="$SEC" + LAST_NUM_KEYCODES=$NUM_KEYCODES + echo "Hooray! we have eleminated some keycodes" + fi + fi + if [ ! -z "$AND_THEN_QUIT" ] + then + RESULT=1 + echo RR 1 + return 1 + fi + if [ ! -z "$LAST_CORE" ] + then + rm "$LAST_CORE" + fi + LAST_CORE="$GDB.core" + else + if ! test -z "$BAK" + then + echo will erase '$BAK/*'="'$BAK/*'" + sleep 2 + rm -rf $BAK/* + mv $OUTDIR/$SEC.* $BAK/ + else + echo "BAK is null" + fi + if [ ! -z "$TAIL_LINES" ] + then + echo TTL3 $TAIL_LINES + echo MAX_TAIL_LINES "$MAX_TAIL_LINES" + TAIL_LINES=$(($TAIL_LINES*2)) + echo TTL4 $TAIL_LINES + if [ "$TAIL_LINES" -ge "0$MAX_TAIL_LINES" -a ! -z "$MAX_TAIL_LINES" ] + then + echo Giving up because $TAIL_LINES '>' $MAX_TAIL_LINES + echo Irreproducible > $OUTDIR/Irreproducible + full_exit + fi + fi + if [ ! -z "$AND_THEN_QUIT" ] + then + RESULT=0 + echo RR 0 + return 0 + fi + + echo TTL2 $TAIL_LINES + fi +} + +test_exist () { + if [ ! -e "$1" ] + then + echo "$1" does not exist! + full_exit 1 + fi +} + +assert () { + if ! "$@" + then + echo "Assertion '$*' Failed!" + full_exit 1 + fi +} + + + +##################################################### +# MAIN +##################################################### + +#Start basic sanity checks + +autolyx_main () { + +if [ ! -e "$EXE_TO_TEST" ] +then + echo "$EXE_TO_TEST" does not exist + echo Cannot proceed + exit +fi + +assert which xvkbd +assert which wmctrl + +if ! wmctrl -l > /dev/null +then + echo autolyx: cannot run wmctrl -l + exit +fi + +test_exist "$EXE_TO_TEST" +test_exist "$DIRNAME0/keytest.py" + +if ! test -z "`pylint -e $DIRNAME0/keytest.py`" +then + echo "$DIRNAME0/keytest.py" has python errors + exit +fi + +ensure_cannot_print + +#End basic sanity checks + +if [ ! -z "$1" ] +then + REPLAYFILE=$1 +fi + +if [ ! -z "$REPLAYFILE" ] +then + echo REPLAYMODE + OUTDIR="$REPLAYFILE.replay/" + mkdirp $REPLAYFILE.replay/ || full_exit + export KEYTEST_INFILE=$REPLAYFILE + if [ ! -e "$REPLAYFILE" ] + then + echo "$REPLAYFILE" does not exist + echo exiting + full_exit 1 + fi +else + do_queued_replays + echo RANDOM MODE +fi + +get_pid [0-9].x-session-manager"$" x +export X_PID=`get_pid [0-9].x-session-manager x` +echo X_PID $X_PID + +export TAIL_LINES=$TAIL_LINES +echo TL $TAIL_LINES + + +BAK="$OUTDIR/backup" +mkdirp $BAK + + + + +#rename other windows to avoid confusion. +wmctrl -N __renamed__ -r lyx +wmctrl -N __renamed__ -r lyx +wmctrl -N __renamed__ -r lyx +wmctrl -N __renamed__ -r lyx +export PATH=`cd $DIRNAME0; pwd`/path:$PATH + +if [ ! -z "$1" ] +then + SEC=`date +%s` + export MAX_DROP=0 + if [ ".$SCREENSHOT_OUT." = ".auto." ] + then + echo SCREENSHOT_OUT was $SCREENSHOT_OUT. + export SCREENSHOT_OUT="$OUTDIR/$SEC.s" + echo SCREENSHOT_OUT is $SCREENSHOT_OUT. + #exit + fi + export RESULT=179 + do_one_test #| tee do_one_test.log + RESULT="$?" + echo Ressult $RESULT + + kill `list_all_children.sh $$` + sleep 0.1 + kill -9 `list_all_children.sh $$` + + exit $RESULT + + #echo done ; sleep 1 + full_exit +fi + + + +( +echo TTL $TAIL_LINES + +LAST_EVENT=`date +%s` # Last time something interesting happened. If nothing interesting has happened for a while, we should quit. + +ensure_cannot_print +echo X_PID $X_PID +export X_PID=`get_pid [0-9].x-session-manager"$" x` +echo PATH $PATH +while true +do + echo Currently running autolyx PID=$$ + if [ ! -z "$TAIL_LINES" ] + then + echo TAIL_LINES: "$TAIL_LINES" + TAIL_FILE=$OUTDIR/tail_"$TAIL_LINES" + tail -n "$TAIL_LINES" "$REPLAYFILE" > $TAIL_FILE + KEYTEST_INFILE=$TAIL_FILE + MAX_DROP=0 + else + MAX_DROP=0.2 + fi + export MAX_DROP + SEC=`date +%s` + if [ -z "$TAIL_LINES" -a ! -z "$REPLAYFILE" ] + then + echo Boredom factor: $SEC-$LAST_EVENT'=' $(($SEC-$LAST_EVENT)) + if [ $(($SEC-$LAST_EVENT)) -gt $BORED_AFTER_SECS ] + then + echo + echo Is is now $SEC seconds + echo The last time we managed to eliminate a keycode was at $LAST_EVENT + echo We get bored after $BORED_AFTER_SECS seconds + echo Giving up now. + echo + echo $LAST_CRASH_SEC > $OUTDIR/Finished + SEC=$LAST_CRASH_SEC #I used SEC in place of LAST_CRASH_SEC. Here is a quick fix. + #make screenshots + if [ `cat $OUTDIR/$SEC.KEYCODEpure | wc -l` -lt 40 ] # If many keycodes, dont bother trying to make screenshots + then + echo "Making screenschot of $OUTDIR/$SEC.KEYCODEpure" + test -e $OUTDIR/$SEC.KEYCODEpure || echo "DOES NOT EXIST: $OUTDIR/$SEC.KEYCODEpure" + (SCREENSHOT_OUT="auto" ./doNtimes.sh 9 ./reproduce.sh $OUTDIR/$SEC.KEYCODEpure ; echo $f ) + fi + mkdirp $OUTDIR/final + mkdirp $OUTDIR/final_cp + #chmod g+w $OUTDIR/final + ln $OUTDIR/$SEC* $OUTDIR/final || cp $OUTDIR/$SEC* $OUTDIR/final + cp $OUTDIR/$SEC* $OUTDIR/final_cp/ + cp -rv $OUTDIR/$SEC.replay $OUTDIR/final_cp/ + CONFIRM_FILE=`calc_confirm_file` + echo Reproducible > "$CONFIRM_FILE" + + + full_exit + fi + else + do_queued_replays + fi + do_one_test +done +kill_all_children $$ +) 2>&1 |tee $OUTDIR/log +kill_all_children $$ +} diff --git a/development/keystest/shared_variables.sh b/development/keystest/shared_variables.sh new file mode 100644 index 0000000000..1fcab84d85 --- /dev/null +++ b/development/keystest/shared_variables.sh @@ -0,0 +1,3 @@ +DIRNAME0=`dirname "$0"` +OUT_NAME=out.2 +ROOT_OUTDIR="$DIRNAME0/$OUT_NAME" diff --git a/development/keystest/view:1 b/development/keystest/view:1 new file mode 100755 index 0000000000..39fc608c4c --- /dev/null +++ b/development/keystest/view:1 @@ -0,0 +1,3 @@ +(DISPLAY=:1 import -window root /tmp/:1.png) +#gwenview /tmp/:1.png +eog /tmp/:1.png diff --git a/development/keystest/watch_keytest.sh b/development/keystest/watch_keytest.sh index 150f77ab43..9893cf0f0a 100755 --- a/development/keystest/watch_keytest.sh +++ b/development/keystest/watch_keytest.sh @@ -1,26 +1,27 @@ - +. ./shared_variables.sh +OUT="$ROOT_OUTDIR" NOW_SEC=`date +%s` echo NOW_SEC $NOW_SEC echo recently modified files: -LATEST_FILE=`ls out/* -td -1 | grep -v log | head -n1` +LATEST_FILE=`ls $ROOT_OUTDIR/* -td -1 | grep -v log | head -n1` echo $LATEST_FILE | ( grep replay > /dev/null || ( - ls out/* -lotd | head + ls $ROOT_OUTDIR/* -lotd | head -n6 ) ) -ls out/* -tdo -1 | grep replay |head -n4 +ls $ROOT_OUTDIR/* -tdo -1 | grep replay |head -n4 -LATEST_FILE=`ls out/* -td -1 | grep replay | head -n1` -if [ $LATEST_FILE = "out/toreplay" ] +LATEST_FILE=`ls $ROOT_OUTDIR/* -td -1 | grep replay | head -n1` +if [ $LATEST_FILE = "$ROOT_OUTDIR/toreplay" ] then #echo foo - LATEST_FILE=`ls out/toreplay/* -td -1 | grep replay | head -n1` + LATEST_FILE=`ls $ROOT_OUTDIR/toreplay/* -td -1 | grep replay | head -n1` fi -if [ $LATEST_FILE = "out/toreplay/replayed" ] +if [ $LATEST_FILE = "$ROOT_OUTDIR/toreplay/replayed" ] then echo foo - LATEST_FILE=`ls out/toreplay/replayed/* -td -1 | grep replay | head -n1` + LATEST_FILE=`ls $ROOT_OUTDIR/toreplay/replayed/* -td -1 | grep replay | head -n1` else echo oof fi @@ -35,14 +36,14 @@ echo $LATEST_FILE | ( echo $SEC $(($NOW_SEC-$SEC)) ls -l $LATEST_FILE/$SEC.KEYCODEpure | head -n4 echo `cat $LATEST_FILE/$SEC.KEYCODEpure | sed s/KK:\//g` - cat $LATEST_FILE/$SEC.GDB | grep "signal SIG" -A 15 + cat $LATEST_FILE/$SEC.GDB | grep "signal SIG" -A 10 else ls $LATEST_FILE -lot | head - cat `echo $LATEST_FILE | sed s/KEYCODEpure.replay/GDB/` | grep "signal SIG" -A 29 + cat `echo $LATEST_FILE | sed s/KEYCODEpure.replay/GDB/` | grep "signal SIG" -A 19 fi cat $LATEST_FILE/log | grep Bore | tail -n2 ) || ( - ls out/* -lotd | head + ls $ROOT_OUTDIR/* -lotd | head ) ) @@ -51,11 +52,11 @@ grep -F "autolyx: Trace reproduced X_PID -x-session" out/log | grep -v kill | grep -v Terminated | tail -n 9 +x-session" $ROOT_OUTDIR/log | grep -v kill | grep -v Terminated | tail -n 9 #exit echo autolyx crashes --------- -grep autolyx: out/log | grep -v kill | grep -v Terminated #-A 5 +grep autolyx: $ROOT_OUTDIR/log | grep -v kill | grep -v Terminated #-A 5 echo python crashes --------- -grep -i -a Trace out/log -A 7 | tail -n8 +grep -i -a Trace $ROOT_OUTDIR/log -A 7 | tail -n8 #echo misc ---- -#grep reproduced out/log | tail -n5 +#grep reproduced $ROOT_OUTDIR/log | tail -n5