Next keystest patch from John McCabe-Dansted.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@32820 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Pavel Sanda 2010-01-06 22:11:59 +00:00
parent 7d20bbeb05
commit ce4b91c109
8 changed files with 89 additions and 28 deletions

View File

@ -27,12 +27,18 @@ maketar.sh: Makes this tar file :)
keytest.py: Sends randomly generated keypresses to the LyX window. keytest.py: Sends randomly generated keypresses to the LyX window.
killtest: stop the testing killtest: stop the testing
stock_text: The stock test to add to each bug report. stock_text: The stock test to add to each bug report.
watch_keytest.sh: Dumps various info on what keytest is doing, often run as "watch watch_keytest.sh"
OUTPUTS: OUTPUTS:
autolyx: Outputs out/*.GDB, a log of all output, including backtraces. autolyx: Outputs out/*.GDB, a log of all output, including backtraces.
keytest.py: Outputs out/*.KEYCODES, a list of all keycodes sent to LyX keytest.py: Outputs out/*.KEYCODES, a list of all keycodes sent to LyX
TIPS:
To reduce the degree to which keytest writes to your HDD, you may want to run
mount -t tmpfs -o size=50m tmpfs /home/keytest/kt.dir
as root
AUTHOR: AUTHOR:
Copyright (C) 2009 John McCabe-Dansted, gmatht at gmail dot com. Copyright (C) 2009 John McCabe-Dansted, gmatht at gmail dot com.
Published under the Gnu General Public Licence, version 2 or later. Published under the Gnu General Public Licence, version 2 or later.

View File

@ -1,3 +1,14 @@
Short Term
Fix gdb PID bug, use readlink -f lyx/src/lyx
Make WANT_CRASH_ID optional
Force all Titles to start with lyx::
Start moving out lyx specific stuff
Make variables customisable
Longer Term
Move all temporary files to a single dir which can be mounted as a tmpfs to reduce HDD writes
HTML out with links. HTML out with links.
Try to get KEYCODES to be repeatible and useable (DONE) Try to get KEYCODES to be repeatible and useable (DONE)
semi protect home dir for repeatibility. semi protect home dir for repeatibility.
@ -9,4 +20,5 @@ If come across different bug when trying to reproduce another, reproduce *both*
Add report as to how easy bug is to reproduce Add report as to how easy bug is to reproduce
Try e.g. electric fence Try e.g. electric fence
Automatically update from svn every 24 hours, recheck if bugs have been fixed. Automatically update from svn every 24 hours, recheck if bugs have been fixed.
Make it easy to use Xvfb instead of VM. Make it easy to use Xvfb instead of VM. (Done)
Automatically add bisect to bug report.

View File

@ -15,6 +15,8 @@ import subprocess
print 'Beginning keytest.py' print 'Beginning keytest.py'
FNULL = open('/dev/null', 'w')
DELAY = '59' DELAY = '59'
class CommandSource: class CommandSource:
@ -103,7 +105,7 @@ class CommandSourceFromFile(CommandSource):
drop = random.randint(0, len(self.lines) - 1) drop = random.randint(0, len(self.lines) - 1)
del self.lines[drop] del self.lines[drop]
p = p - 1 / len(self.lines) #p = p - 1 / len(self.lines)
origlines = self.lines origlines = self.lines
self.lines = [] self.lines = []
for l in origlines: for l in origlines:
@ -144,7 +146,8 @@ class CommandSourceFromFile(CommandSource):
line = self.lines[self.i] line = self.lines[self.i]
self.count = self.count + 1 self.count = self.count + 1
self.i = self.i + 1 self.i = self.i + 1
print 'Line read: <<' + line + '>>\n' #print 'Line read: <<' + line + '>>\n'
sys.stdout.write('r')
return line.rstrip('\n').rstrip() return line.rstrip('\n').rstrip()
@ -171,7 +174,7 @@ def sendKeystring(keystr, LYX_PID):
before_secs = time.time() before_secs = time.time()
while not lyx_sleeping(): while not lyx_sleeping():
time.sleep(0.02) time.sleep(0.02)
print '.', sys.stdout.write('.')
if time.time() - before_secs > 180: if time.time() - before_secs > 180:
print 'Killing due to freeze (KILL_FREEZE)' print 'Killing due to freeze (KILL_FREEZE)'
@ -188,7 +191,13 @@ def sendKeystring(keystr, LYX_PID):
os.system('import -window root '+screenshot_out+str(x.count)+".png") os.system('import -window root '+screenshot_out+str(x.count)+".png")
time.sleep(0.1) time.sleep(0.1)
sys.stdout.flush() sys.stdout.flush()
subprocess.call(["xvkbd", "-xsendevent", "-delay", DELAY, "-text", keystr]) if (subprocess.call(
["xvkbd", "-xsendevent", "-delay", DELAY, "-text", keystr],
stdout=FNULL,stderr=FNULL
) == 0):
sys.stdout.write('*')
else:
sys.stdout.write('X')
def system_retry(num_retry, cmd): def system_retry(num_retry, cmd):
i = 0 i = 0
@ -253,7 +262,7 @@ sendKeystring("\Afn", lyx_pid)
write_commands = True write_commands = True
while True: while True:
os.system('echo -n LOADAVG:; cat /proc/loadavg') #os.system('echo -n LOADAVG:; cat /proc/loadavg')
c = x.getCommand() c = x.getCommand()
if c == 'Loop': if c == 'Loop':
outfile.close() outfile.close()

View File

@ -1,9 +1,19 @@
#PWD=`pwd` #PWD=`pwd`
. ./shared_variables.sh
if [ "$USER" != keytest ] if [ "$USER" != keytest ]
then then
echo USER is "$USER", not keytest! Exiting. echo USER is "$USER", not keytest! Exiting.
exit exit
fi fi
for file in $ROOT_OUTDIR/to*/*pure
do
if ! cat $file > /dev/null
then
echo cannot read $file, perhaps permissions are wrong?
exit 1
fi
done
#(DISPLAY=:1 sudo -u keytest -H nice -18 ; cd $PWD ; ./autolyx) #(DISPLAY=:1 sudo -u keytest -H nice -18 ; cd $PWD ; ./autolyx)
./killtest.sh # kill any previous test, so does not interfere ./killtest.sh # kill any previous test, so does not interfere
./autolyx ./autolyx

View File

@ -32,10 +32,16 @@ cat $LT/$OUT_NAME/list | sed 's/0x[^ )]*[ )]/.*/g' | sort | uniq | tee $LT/$OUT
echo '<html>' >> $OUT/indexreport.html echo '<html>' >> $OUT/indexreport.html
list_keycode_files () { list_keycode_files () {
echo for f in $OUT_NAME/*y/last_crash_sec $OUT_NAME/toreplay/replayed/*y/last_crash_sec #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 for f in $OUT_NAME/*y/last_crash_sec $OUT_NAME/toreplay/replayed/*y/last_crash_sec $OUT_NAME/toreproduce/replayed/*y/last_crash_sec $OUT_NAME/toreplay/*y/last_crash_sec $OUT_NAME/toreplay/final/*y/last_crash_sec
#for f in $OUT_NAME/*y/*y/last_crash_sec $OUT_NAME/toreplay/replayed/*y/*y/last_crash_sec $OUT_NAME/toreplay/*y/*y/last_crash_sec $OUT_NAME/toreplay/final/*y/last_crash_sec
do do
keycode_file=$(echo $f | sed s/last_crash_sec/$(cat $f).KEYCODEpure/) keycode_file=$(echo $f | sed s/last_crash_sec/$(cat $f).KEYCODEpure/)
if test -e $keycode_file.replay/last_crash_sec
then
f=$keycode_file.replay/last_crash_sec
keycode_file=$(echo $f | sed s/last_crash_sec/$(cat $f).KEYCODEpure/)
fi
echo $keycode_file echo $keycode_file
done done
} }
@ -134,8 +140,8 @@ do
echo cpp $cpp echo cpp $cpp
lineno=`echo "$c" | sed 's/.*://g'` lineno=`echo "$c" | sed 's/.*://g'`
echo $cpp,$lineno 1>&2 echo $cpp,$lineno 1>&2
#if [ -e "$CPP_HTML_DIR/$cpp.html" ] if [ -e "$CPP_HTML_DIR/$cpp.html" ]
if true #if true
then then
#echo "$l" | sed "s/$c/<a href=$CPP_HTML_DIR_REL\/$cpp.html\#line$lineno>$c<\/a>/" #echo "$l" | sed "s/$c/<a href=$CPP_HTML_DIR_REL\/$cpp.html\#line$lineno>$c<\/a>/"
echo "$l" | sed "s?$c?<a href=$CPP_HTML_DIR_REL\/$cpp.html\#line$lineno>$c<\/a>?" echo "$l" | sed "s?$c?<a href=$CPP_HTML_DIR_REL\/$cpp.html\#line$lineno>$c<\/a>?"
@ -174,7 +180,7 @@ if ! test -e $ROOT_OUTDIR/html/cpp_html
then then
(mkdir -p $ROOT_OUTDIR/html/cpp_html/ && (mkdir -p $ROOT_OUTDIR/html/cpp_html/ &&
cd $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) for f in `find ../../../src/ -iname '*.cpp' ; find ../../../src/ -iname '*.h'` ; do g=`basename $f`; c2html -n < $f > $g.html ; echo $f ; done)
fi fi
} }
@ -215,18 +221,23 @@ do
echo f_base $f_base echo f_base $f_base
NUM_KEYCODES=`wc -l < "$f_base.KEYCODEpure"` NUM_KEYCODES=`wc -l < "$f_base.KEYCODEpure"`
echo NUM_KEYCODES=$NUM_KEYCODES... echo NUM_KEYCODES=$NUM_KEYCODES...
if [ "$NUM_KEYCODES" -lt 10 ] if [ "$NUM_KEYCODES" -lt 20 ]
then then
echo f_base $f_base echo f_base $f_base
f=$f_base.GDB f=$f_base.GDB
echo $f echo $f
g=$f.short g=$f.short
egrep '([Ii][Nn] .*[:[:alnum:]][:][0-9]*[^0-9]|#0 | signal SIG[^T])' -A9999 <$f >$g #egrep '([Ii][Nn] .*[:[:alnum:]][:][0-9]*[^0-9]|#0 | signal SIG[^T]| ASSERTION .* VIOLATED IN )' -A9999 <$f >$g
egrep '([Ii][Nn] .*[:[:alnum:]][:][0-9]*[^0-9]|#0 | signal SIG[^T]| ASSERTION .* VIOLATED IN )' -A9999 <$f >$g
if true if true
then then
IN_AT=`egrep -o '([Ii][Nn]|at) ([:lower:]* )?[:_[:alnum:]]*(::[:_[:alnum:]]*|:[0-9]*)' <$f | grep -v lyx_exit | grep -v [Aa]ssert | head -n 1 ` IN_AT=`egrep -o '([Ii][Nn]|at) ([:lower:]* )?[:_[:alnum:]]*(::[:_[:alnum:]]*|:[0-9]*)' <$f | grep -v lyx_exit | grep -v [Aa]ssert | head -n 1 `
SIGNAL=`grep -o ' signal SIG[[:alnum:]_]*[, ]' <$g | sed s/[^[:upper:]]//g | head -n 1` SIGNAL=`grep -o ' signal SIG[[:alnum:]_]*[, ]' <$g | sed s/[^[:upper:]]//g | head -n 1`
TITLE="$SIGNAL $IN_AT" TITLE="$SIGNAL $IN_AT"
if grep ' ASSERTION .* VIOLATED IN ' $g
then
TITLE=`grep -o ' ASSERTION .* VIOLATED IN .*$' $g`
fi
TITLE_=`echo $TITLE|sed s/[^[:alnum:]]/_/g` TITLE_=`echo $TITLE|sed s/[^[:alnum:]]/_/g`
INDEX="index.html" INDEX="index.html"
HTML_NAME=$SEC.html # name of html report for this bug HTML_NAME=$SEC.html # name of html report for this bug
@ -236,11 +247,13 @@ do
echo '<html>' >> $LT/$OUT_NAME/$INDEX echo '<html>' >> $LT/$OUT_NAME/$INDEX
(echo -n "<br/><a href=\"$SEC.html\">$TITLE</a> " (echo -n "<br/><a href=\"$SEC.html\">$TITLE</a> "
html_keycode html_keycode
echo " [<a href=\"`search_bug_url`\">search</a>] [<a href=\"`report_bug_url`\">report</a>] <a href=\"$SEC.screenshot.html\">screenshots</a>" #echo -n " [<a href=\"`search_bug_url`\">search</a>] [<a href=\"`report_bug_url`\">report</a>] <a href=\"$SEC.screenshot.html\">screenshots</a>"
#if ls $f_base.s*.png echo -n " [<a href=\"`search_bug_url`\">search</a>] [<a href=\"`report_bug_url`\">report</a>]"
#then if ls $f_base.s*.png > /dev/null
# echo "<a href=\"$SEC.screenshot.html\">screenshots</a>" then
#fi echo -n " <a href=\"$SEC.screenshot.html\">screenshots</a>"
fi
echo
#echo -n '<br/> ' #echo -n '<br/> '
echo ) >> $OUT/indexreport.html echo ) >> $OUT/indexreport.html
echo -n '<br> '>> $LT/$OUT_NAME/$INDEX echo -n '<br> '>> $LT/$OUT_NAME/$INDEX

View File

@ -4,9 +4,6 @@ OUTDIR="$ROOT_OUTDIR"
#OUTDIR="$DIRNAME0/out" #OUTDIR="$DIRNAME0/out"
THIS_PID=$$ THIS_PID=$$
SRC_DIR=lyx/src
EXE_TO_TEST=$SRC_DIR/lyx
#kill(){ #kill(){
# echo kill # echo kill
#} #}
@ -109,7 +106,7 @@ get_pid () {
sleep 3 sleep 3
echo getting pidof "$1" 1>&2 echo getting pidof "$1" 1>&2
#PID=`ps "-u$USER" "$2" | grep "$1" | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'` #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/ .*$//'` PID=`ps x | grep "$1" | grep -v grep | grep -v "gdb " | sed 's/^ *//g'| sed 's/ .*$//'`
echo "$PID" | ( grep " " > /dev/null && ( echo ERROR too many PIDs 1>&2 ; ps x ; full_exit ) ) echo "$PID" | ( grep " " > /dev/null && ( echo ERROR too many PIDs 1>&2 ; ps x ; full_exit ) )
nPIDs=`echo PID "$PID" | wc -l` nPIDs=`echo PID "$PID" | wc -l`
echo nPIDs $nPIDs 1>&2 echo nPIDs $nPIDs 1>&2
@ -167,7 +164,7 @@ run_gdb () {
bt bt
#shell kill $CHILD_PID #shell kill $CHILD_PID
shell wmctrl -l shell wmctrl -l
#shell sleep 1 shell sleep 1
#shell kill -9 $CHILD_PID #shell kill -9 $CHILD_PID
" ; yes q) | HOME="$NEWHOME" gdb $EXE_TO_TEST 2>&1 | strings| tee $GDB " ; yes q) | HOME="$NEWHOME" gdb $EXE_TO_TEST 2>&1 | strings| tee $GDB
echo "end run_gdb ($KILLER_PID)" echo "end run_gdb ($KILLER_PID)"
@ -201,7 +198,9 @@ try_replay () {
echo This bug appears not to have been reproduced before echo This bug appears not to have been reproduced before
echo Will try to reproduce now echo Will try to reproduce now
echo echo
do_replay echo WANT_CRASH_ID=$WANT_CRASH_ID
WANT_CRASH_ID="$id" do_replay
echo _WANT_CRASH_ID=$WANT_CRASH_ID
echo echo
echo Finished attempt at replay echo Finished attempt at replay
else else
@ -268,6 +267,11 @@ echo done queued_replays
) )
} }
interesting_crash () {
(grep " signal SIG[^TK]" $GDB || grep KILL_FREEZE $KEYCODE) &&
( test -z "$WANT_CRASH_ID" || test "$WANT_CRASH_ID" = `get_crash_id` )
}
#get_pid() { #get_pid() {
# ps a | grep $1 | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//' # ps a | grep $1 | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'
#} #}
@ -374,7 +378,8 @@ do_one_test() {
echo will erase "$NEWHOME" echo will erase "$NEWHOME"
sleep 2 sleep 2
rm -rf $NEWHOME rm -rf $NEWHOME
if (grep " signal SIG[^TK]" $GDB || grep KILL_FREEZE $KEYCODE) #if (grep " signal SIG[^TK]" $GDB || grep KILL_FREEZE $KEYCODE)
if interesting_crash
then then
extras_save extras_save
mkdirp $OUTDIR/save && ( mkdirp $OUTDIR/save && (

View File

@ -1,3 +1,7 @@
DIRNAME0=`dirname "$0"` DIRNAME0=`dirname "$0"`
OUT_NAME=out.2 OUT_NAME=out/3
ROOT_OUTDIR="$DIRNAME0/$OUT_NAME" ROOT_OUTDIR="$DIRNAME0/$OUT_NAME"
SRC_DIR=lyx/src
EXE_TO_TEST=$SRC_DIR/lyx
EXE_TO_TEST=`readlink -f "$EXE_TO_TEST"` # softlinks can confuse "ps"

View File

@ -36,7 +36,9 @@ echo $LATEST_FILE | (
echo $SEC $(($NOW_SEC-$SEC)) echo $SEC $(($NOW_SEC-$SEC))
ls -l $LATEST_FILE/$SEC.KEYCODEpure | head -n4 ls -l $LATEST_FILE/$SEC.KEYCODEpure | head -n4
echo `cat $LATEST_FILE/$SEC.KEYCODEpure | sed s/KK:\//g` echo `cat $LATEST_FILE/$SEC.KEYCODEpure | sed s/KK:\//g`
cat $LATEST_FILE/$SEC.GDB | grep "signal SIG" -A 10 cat $LATEST_FILE/$SEC.GDB | grep "VIOLATED" #-A 15 -B 5
cat $LATEST_FILE/$SEC.GDB | grep "signal SIG" #-A 15 -B 5
cat $LATEST_FILE/$SEC.GDB | grep "lyx::" | head -n5 #-A 15 -B 5
else else
ls $LATEST_FILE -lot | head ls $LATEST_FILE -lot | head
cat `echo $LATEST_FILE | sed s/KEYCODEpure.replay/GDB/` | grep "signal SIG" -A 19 cat `echo $LATEST_FILE | sed s/KEYCODEpure.replay/GDB/` | grep "signal SIG" -A 19
@ -55,7 +57,7 @@ X_PID
x-session" $ROOT_OUTDIR/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 #exit
echo autolyx crashes --------- echo autolyx crashes ---------
grep autolyx: $ROOT_OUTDIR/log | grep -v kill | grep -v Terminated #-A 5 grep autolyx: $ROOT_OUTDIR/log | grep -v kill | grep -v Terminated | grep -v grep #-A 5
echo python crashes --------- echo python crashes ---------
grep -i -a Trace $ROOT_OUTDIR/log -A 7 | tail -n8 grep -i -a Trace $ROOT_OUTDIR/log -A 7 | tail -n8
#echo misc ---- #echo misc ----