]> git.lyx.org Git - features.git/commitdiff
Next patch for keystest from John McCabe-Dansted.
authorPavel Sanda <sanda@lyx.org>
Sat, 3 Oct 2009 23:07:44 +0000 (23:07 +0000)
committerPavel Sanda <sanda@lyx.org>
Sat, 3 Oct 2009 23:07:44 +0000 (23:07 +0000)
http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg154502.html

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@31495 a592a061-630c-0410-9148-cb99ea01b6c8

development/keystest/autolyx
development/keystest/cache-bisect.py [new file with mode: 0755]
development/keystest/cache-bisect.sh [new file with mode: 0755]
development/keystest/doNtimes.sh [new file with mode: 0755]
development/keystest/keytest.py
development/keystest/killtest.sh
development/keystest/killtestpy.sh [changed mode: 0644->0755]
development/keystest/list_all_children.sh [new file with mode: 0755]
development/keystest/make_screenshot_html.py [new file with mode: 0755]
development/keystest/report_html.sh
development/keystest/watch_keytest.sh

index 228fd12b1254c12d9c9d228db0563b99d47aaafc..bf9f48ad1fbba58b5bc1459d72d1e9af68801ed5 100755 (executable)
@@ -10,33 +10,67 @@ 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 lib/doc.orig ]
+if [ ! -e $DIRNAME0/.lyx ]
 then
-       mv lib/doc lib/doc.orig
+       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 () {
-lpq && ( 
+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
+               #echo making doc dir $OUTDIR/$SEC.doc
                mkdir -p $OUTDIR/$SEC.doc
                cp -a lib/doc/$f $OUTDIR/$SEC.doc/
        fi
@@ -44,6 +78,7 @@ extras_save () {
 }
 
 extras_prepare () {
+       return
        mkdir -p lib/doc/
        rm lib/doc/*.lyx
        cp -p lib/doc.orig/*.lyx lib/doc/
@@ -59,31 +94,71 @@ calc_confirm_file() {
        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_PIS
-       echo We really should not get this far
+       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
+}
+
+
 ###########################
 
-get_pid () {
-       echo getting pidof "$1" 1>&2
-       PID=`ps a"$2" | 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`
-       if [ "$nPIDs" != "1" ]
-       then 
-               echo autolyx: Wrong number of PIDs "$nPIDs" 1>&2
-       fi
-       echo "$PID"
-}
+
 
 try_replay () {
        id=`get_crash_id`
@@ -113,101 +188,42 @@ do_replay() {
        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() {
-for f in `ls development/keytest/out/toreplay/*KEYCODEpure`
+REPLAY_DIR=development/keytest/out/toreplay
+for f in `ls $REPLAY_DIR/*KEYCODEpure`
 do
-       if [ ! -e "$f.replay/last_crash_sec" ]
+       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/ .*$//'
+#}
 
-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
-(
-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
-               CONFIRM_FILE=`calc_confirm_file`
-               echo Reproducible > "$CONFIRM_FILE"
-               
-               
-               full_exit
-       fi
- fi
-
+do_one_test() {
   GDB=$OUTDIR/$SEC.GDB
   KEYCODE=$OUTDIR/$SEC.KEYCODE
   KEYCODEpure=$OUTDIR/$SEC.KEYCODEpure
@@ -216,17 +232,19 @@ do
   NEWHOME=`cd $NEWHOME; pwd`
   echo NEWHOME $NEWHOME
   mkdir -p "$NEWHOME"
-  cp -rv ~/.lyx "$NEWHOME"/
-  killall -9 lyx
-  ( sleep 25 &&
+  cp -rv $DIRNAME0/.lyx "$NEWHOME"/
+  killall -9 lyx latex pdflatex
+  ( sleep 9 &&
      ps a | grep lyx 
-       echo -- 1
+       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/ .*$//'`
-            echo LYXPID "$LYX_PID"
+            #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 
@@ -241,12 +259,19 @@ do
      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="$!"
@@ -258,30 +283,32 @@ do
   echo TTL $TAIL_LINES
   extras_prepare
   ensure_cannot_print
-  echo Starting GDB
-  (echo "
-  shell svn info src/
-  run
-  bt
-  shell kill $CHILD_PID
-  shell import -window root '$GDB.png'
-  shell wmctrl -l
-  shell sleep 1
-  shell kill -9 $CHILD_PID
-  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'
- " ; yes q) | HOME="$NEWHOME" gdb src/lyx 2>&1 | strings|  tee $GDB
+  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":
-  if grep " signal SIG[^T]" $GDB 
+  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" ]
@@ -305,8 +332,19 @@ do
                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 -r $BAK/* 
+    rm -rf $BAK/* 
     mv $OUTDIR/$SEC.* $BAK/
     if [ ! -z "$TAIL_LINES" ]
      then
@@ -321,7 +359,137 @@ do
                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 $$
diff --git a/development/keystest/cache-bisect.py b/development/keystest/cache-bisect.py
new file mode 100755 (executable)
index 0000000..e379743
--- /dev/null
@@ -0,0 +1,321 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import os
+from subprocess import call, check_call
+from random import randrange
+import getpass
+
+
+outfilename = "/tmp/cache-bisect." + getpass.getuser() + ".log"
+outfile = open(outfilename, 'w')
+print 'BBBISECT_BEGIN'
+#print >> outfile, 'BBBISECT_BEGIN'
+#print >> outfile, 'BBBISECT_BEGIN'
+#print >> outfile, 'BBBISECT_BEGIN'
+#print >> outfile, 'BBBISECT_BEGIN'
+#print >> outfile, 'BBBISECT_BEGIN'
+#print 'BBBISECT_BEGIN'
+
+source_dir = '/mnt/big/xp/src/lyx-1.6.x-bisect'  # must NOT end in a slash
+cache_dir = source_dir + '.cache/'  # must end in a slash
+source_dir = '/mnt/big/xp/src/lyx-1.6.x-bisect2'  # must NOT end in a slash
+
+#make_cmd = 'autoconf && ./configure && cd src && echo __________ `pwd` && sleep 9 && make'
+make_cmd = 'rm -rf autom4te.cache && autoconf && ./configure && cd src && make'
+
+reverse_search = True
+reverse_search = False
+must_make = True  # If we fail to make the file, we could this a "bad" rather than "canot test"
+must_make = False
+
+# ToDo:
+# replace .tmp with .partial_copy and .not_yet_made
+
+
+def set_revision(new_v, tmp_d):
+    #check_call(['svn', 'up', '-r' + new_v, '--force'], cwd=tmp_d)
+    os.system ('cd "'+tmp_d+'" && yes tf | svn up -r'+new_v+'--force')
+
+def cmp_version(x, y):
+    return cmp(int(x), int(y))
+
+
+def get_cached_versions():
+    vers = [f for f in os.listdir(cache_dir) if not f.count('.')]
+    vers.sort(cmp_version)
+    return vers
+
+
+def version_in_range(v, lo, hi):
+    if cmp_version(v, lo) < 0:
+        return False
+    elif cmp_version(v, hi) > 0:
+        return False
+    return True
+
+def killall_p (s):
+    # Unlike killall, this searchs within command parameters, as well as the
+    # command name
+
+        #os.system("kPID=`ps a | grep '"+s+"' | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'`
+    os.system("(kPID=`ps a | grep '"+s+
+    "' | grep -v grep | sed 's/^ *//g'|  sed 's/ .*$//'`\n\
+        echo kPID $kPID "+s+"\n\
+        echo kill $kPID\n\
+        kill $kPID\n\
+        sleep 0.1\n\
+        echo kill -9 $kPID\n\
+        kill -9 $kPID) 2> /dev/null")
+
+def clean_up ():
+    killall_p("autolyx")
+    killall_p("lyx")
+    killall_p("keytest.py")
+    killall_p("xclip")
+
+def filter_versions(vers, lo, hi):
+    return [v for v in vers if cmp]
+
+
+def ver2dir(v):
+    return cache_dir + v
+
+
+def make_ver(new_v, old_v=None, alt_v=None):
+    print 'MAKING', new_v, old_v, alt_v
+    new_d = ver2dir(new_v)
+    if old_v is None:
+        old_d = source_dir
+    else:
+        old_d = ver2dir(old_v)
+    fail_d = new_d + '.fail'
+    tmp_d = new_d + '.tmp'
+    if os.path.exists(cache_dir + fail_d):
+        return 1
+    if os.path.exists(new_d):
+        return 0
+    if not os.path.exists(tmp_d):
+        if not os.path.exists(old_d):
+            old_d = old_d + '.tmp'
+        call(['rm', '-rf', tmp_d + '.cp'])
+        call(['cp', '-rvu', old_d, tmp_d + '.cp'])
+        check_call(['mv', tmp_d + '.cp', tmp_d])
+        set_revision(new_v, tmp_d)
+    call('pwd && sleep 5 && echo ' + make_cmd, cwd=tmp_d, shell=True)
+    result = call(make_cmd, cwd=tmp_d, shell=True)
+    if result == 0:
+        print 'Make successful'
+        check_call(['mv', tmp_d, new_d])
+    return result
+
+
+def change_after(cmd, v):
+    result = run_cmd(cmd, v)
+    ca = result_after(result)
+    print >> outfile, 'BISECT_change_after', v, ca
+    print 'BISECT_change_after', v, ca
+    return ca
+
+
+def change_before(cmd, v):
+    result = run_cmd(cmd, v)
+    cb = result_before(result)
+    print >> outfile, 'BISECT_change_before', v, cb
+    print 'BISECT_change_before', v, cb
+    return cb
+
+
+def result_after(i):
+    if reverse_search:
+        return result_bad(i)
+    else:
+        return result_good(i)
+
+
+def result_before(i):
+    if reverse_search:
+        return result_good(i)
+    else:
+        return result_bad(i)
+
+
+def result_good(i):
+    return i == 0
+
+
+def result_bad(i):
+    return not result_ugly(i) and not result_good(i)
+
+
+def result_ugly(i):
+    return i == 125  # Like git, we treat 125 as "We cannot test this version"
+
+
+def run_cmd(cmd, v):
+    #result = call('pwd ; echo SS ' + cmd, shell=True, cwd=ver2dir(v))
+    print "CMD", cmd
+    print "V2D", ver2dir(v)
+    os
+    #result = subprocess.call(cmd, shell=True, cwd=ver2dir(v))
+    result = call(cmd, cwd=ver2dir(v))
+    clean_up()
+    print cmd, result
+    return result
+
+
+def do_bisect(cmd, vers, build):
+    lo = 0
+    hi = len(vers) - 1
+    m = (lo + hi) / 2
+
+    print lo, hi, m
+    print vers[lo], vers[hi], vers[m]
+    print vers
+
+    print >> outfile, 'VERS', final_vers
+
+    while len(vers) > 2:
+        print 'i', lo, hi, m, cmd
+        print 'v', vers[lo], vers[hi], vers[m], cmd
+        print vers
+
+        print '#ugly = Nonese'
+
+        if build or must_make:
+            ugly = False
+            result = make_ver(vers[m], vers[lo], vers[hi])
+            print 'AMKE RESULT', result
+            if not must_make:
+                if result > 0 and not must_make:
+                    ugly = True  # Not good, or bad, just ugly.
+                else:
+                    result = run_cmd(cmd, vers[m])
+        if not ugly:
+            if result > 127:
+                os._exit(1)
+            ugly = result_ugly(result)
+        if ugly:
+            print vers[m] + ' is UGLY'
+            del vers[m]
+            hi = len(vers) - 1
+            m = randrange(0, len(vers))
+        else:
+            if result_after(result):
+                print vers[m] + ' is AFTER'
+                del vers[lo:m]
+            else:
+                print vers[m] + ' is BEFORE'
+                del vers[m + 1:hi + 1]
+            hi = len(vers) - 1
+            m = (lo + hi) / 2
+
+        print 'VERS REMAINING:', vers
+
+    return vers
+
+
+def check_bisect(cmd, vers):
+    lo = 0
+    hi = len(vers) - 1
+    l = vers[lo]
+    h = vers[hi]
+    if make_ver(l):
+        return False
+    if make_ver(h):
+        return False
+    if change_before(cmd, l):
+        print 'Cannot bisect, change before ' + l\
+             + ' or regression test invalid'
+        return False
+    if change_after(cmd, h):
+        print 'Cannot bisect, change after ' + h\
+             + ' or regression test invalid'
+        return False
+    return True
+
+
+def do_check_bisect(cmd, vers, build):
+    print vers
+    if check_bisect(cmd, vers):
+        return do_bisect(cmd, vers, build)
+    else:
+        return
+
+
+def open_and_readlines(fname):
+    f = open(fname, 'r')
+    lines = f.readlines()
+    for i in range(0, len(lines)):
+        lines[i] = lines[i].rstrip('\n')
+    return lines
+
+
+def get_versions_between(l, h):
+    vers = [f for f in open_and_readlines('all_versions')
+            if version_in_range(f, l, h)]
+    vers.sort(cmp_version)
+    return vers
+
+
+def get_cached_versions_between(l, h):
+    vers = [f for f in get_cached_versions() if version_in_range(f, l, h)]
+    vers.sort(cmp_version)
+    print 'BTWN', l, h, vers
+    return vers
+
+
+def two_level_bisect(cmd, LO, HI):
+    if make_ver(LO):
+        return False
+    if make_ver(HI):
+        return False
+    vers = get_cached_versions_between(LO, HI)
+    print 'CACHED_VERSIONS', vers
+    vers = do_check_bisect(cmd, vers, False)
+    print 'Closest Cached Versions', vers
+    if vers is None:
+        return
+    if len(vers) != 2:
+        return
+    vers = get_versions_between(vers[0], vers[1])
+    print 'BETWEEN VERSIONS', vers
+    vers = do_check_bisect(cmd, vers, True)
+
+
+def multisect(cmd, vers):
+    i = 1
+    while i < len(vers):
+        print >> outfile, 'MULTISECT', vers[i]
+        print 'MULTISECT', vers[i]
+        if not ( make_ver(vers[i], vers[i-1])==0 and change_after(cmd, vers[i]) ) :
+            i = i + 1
+        else:
+            return two_level_bisect(cmd, vers[i], vers[0])
+
+
+print 'BISECT_BEGIN'
+print >> outfile, 'BISECT_BEGIN'
+outfile.flush()
+#final_vers = multisect('$TEST_COMMAND', ['30614', '27418', '23000'])
+cmd = os.sys.argv
+del cmd[0]
+
+VERS = os.environ.get('MULTISECT_VERS')
+if VERS is None:
+    VERS = ['30614', '27418', '23000']
+else:
+    VERS = VERS.split()
+
+final_vers = multisect(cmd, VERS)
+#final_vers = two_level_bisect('true', "21107","23000")
+#final_vers = do_bisect('true', get_versions_between("21107","23000"),True)
+outfile.flush()
+print
+print >> outfile, 'BISECT_FINAL', final_vers
+print 'BISECT_FINAL', final_vers
+os.system('echo BISECT_BEGIN >> /tmp/adsfadsf.log')
+os.system('echo BISECT_FINAL >> /tmp/adsfadsf.log')
+
+clean_up()
+os._exit(0)
diff --git a/development/keystest/cache-bisect.sh b/development/keystest/cache-bisect.sh
new file mode 100755 (executable)
index 0000000..a929406
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Cache-bisect is
+# roughly based on git-bisect, but uses SVN and caches every build tree
+# to maximize performance. The idea here is that if the first few tests
+# happen very quickly, and give plausible results, you can have
+# confidence that you can just leave it running. Without that confidence
+# I'd be continually thinking "Is the bisect still working, maybe I
+# should check" so the bisect would be taking up my mental space. With
+# cache-bisect, I can fire-and-forget, leaving the CPU to do the menial
+# tasks while I think about other things. Additionally caching the
+# build-trees cuts down on the amount of bandwidth required on the SVN
+# server
+#  It uses three levels
+#    1) At the bottom level, it bisects much like git-bisect
+#    2) At the second level, it bisects, but only over cached revisions.
+#    3) The the top level it does what I refer to as a "multisect". The
+# idea is that you may not know which revision was a good revision, and
+# picking revision 1 as the "good" revision is not only mildly wasteful
+# but is likely to produce misleading results. Instead it starts
+# stepping backwards, first trying 1.6.0, and then going backwards
+# through trunk.
+
+       KT=$(cd $(dirname "$0") && pwd)
+$KT/cache-bisect.py "$@" | tee out/cache-bisect-$USER.log
+
+
diff --git a/development/keystest/doNtimes.sh b/development/keystest/doNtimes.sh
new file mode 100755 (executable)
index 0000000..0ea176d
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+KT=`dirname $0`
+N=$1
+shift
+
+echo doNtimes .$N. "$@"
+
+i=0
+for intr in `yes | head -n$N`
+do
+       i=$(($i+1))
+       echo 'TRY#' $i
+       if ! "$@"
+       then
+               echo TRIES_REQUIRED: $i
+               exit 1
+       fi
+done
+
+echo DONE $N TIMES
index aacbb4732bf5ac555775ab6c50df6177a5b4a851..4bbe3ce21891827d2deea0fb70fe3efa68d26667 100755 (executable)
-#!/usr/bin/env python
-#This script generated hundreds of random keypresses per second,
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# This script generates hundreds of random keypresses per second,
 #  and sends them to the lyx window
-#It requires xvkbd and wmctrl
-#It generates a log of the KEYCODES it sends as development/keystest/out/KEYCODES
+# It requires xvkbd and wmctrl
+# It generates a log of the KEYCODES it sends as development/keystest/out/KEYCODES
 
 import random
-import os 
+import os
 import re
 import sys
+import time
+#from subprocess import call
+import subprocess
 
-print "Beginning keytest.py"
+print 'Beginning keytest.py'
 
+DELAY = '59'
 
 class CommandSource:
-       def __init__(self):
-               keycode=["\[Left]",'\[Right]','\[Down]','\[Up]','\[BackSpace]','\[Delete]','\[Escape]']
-               keycode[:0]=keycode
-               keycode[:0]=keycode
-
-               keycode[:0]=['\\']
-
-               for k in range(97, 123):
-                 keycode[:0]=chr(k)
-
-               for k in range(97, 123):
-                 keycode[:0]=["\A"+chr(k)]
-
-               for k in range(97, 123):
-                 keycode[:0]=["\A"+chr(k)]
-
-               for k in range(97, 123):
-                 keycode[:0]=["\C"+chr(k)]
-
-               self.keycode=keycode;
-               self.count=0;
-               self.count_max=1999;
-
-       def getCommand(self):
-               self.count=self.count+1;
-               #if self.count > self.count_max:
-               if self.count%200==0:
-                       #self.count=0
-                       return ("RaiseLyx")
-               elif self.count > self.count_max:
-                       os._exit(0)
-               else:
-                       keystr=""
-                       for k in range(1,2):
-                               keystr=keystr+self.keycode[random.randint(1,len(self.keycode))-1]
-                       return "KK: "+keystr
+
+    def __init__(self):
+        keycode = [
+            "\[Left]",
+            '\[Right]',
+            '\[Down]',
+            '\[Up]',
+            '\[BackSpace]',
+            '\[Delete]',
+            '\[Escape]',
+            ]
+        keycode[:0] = keycode
+        keycode[:0] = keycode
+
+        keycode[:0] = ['\\']
+
+        for k in range(97, 123):
+            keycode[:0] = chr(k)
+
+        for k in range(97, 123):
+            keycode[:0] = ["\A" + chr(k)]
+
+        for k in range(97, 123):
+            keycode[:0] = ["\A" + chr(k)]
+
+        for k in range(97, 123):
+            keycode[:0] = ["\C" + chr(k)]
+
+        self.keycode = keycode
+        self.count = 0
+        self.count_max = 1999
+
+    def getCommand(self):
+        self.count = self.count + 1
+        if self.count % 200 == 0:
+            return 'RaiseLyx'
+        elif self.count > self.count_max:
+            os._exit(0)
+        else:
+            keystr = ''
+            for k in range(1, 2):
+                keystr = keystr + self.keycode[random.randint(1,
+                        len(self.keycode)) - 1]
+            return 'KK: ' + keystr
+
 
 class CommandSourceFromFile(CommandSource):
-       def __init__(self,filename,p):
-               self.infile=open(filename,'r')
-               self.lines=self.infile.readlines()
-               self.p=p
-               self.i=0
-               self.count=0
-               self.loops=0
-               #Now we start randomly dropping lines, which we hope are redundant
-               #p is the probability that any given line will be removed
-               if (p>0):
-                       #The next couple of lines are to ensure that at least one line is dropped
-                       drop=random.randint(0,len(self.lines)-1)
-                       del self.lines[drop]
-                       p=p-(1/len(self.lines))
-                       j=0
-                       origlines=self.lines
-                       self.lines=[];
-                       for l in origlines:
-                               if random.uniform(0,1) < self.p:
-                                       print "Randomly dropping line "+l+"\n"
-                               else:
-                                       self.lines.append(l)
-                       print "LINES\n"
-                       print self.lines
-                       sys.stdout.flush()
-                       os.system("sleep 2")
-               
-       def getCommand(self):
-               if self.i >= len(self.lines):
-                       if self.count >= 100 or self.loops>1:
-                               os.system("sleep 1")
-                               os._exit(0)
-                       else:
-                               self.loops=self.loops+1
-                               self.i=0
-                               return("Loop")
-               line=self.lines[self.i]
-               print "Line read: <<"+line+">>\n"
-               self.count=self.count+1
-               self.i=self.i+1
-               return(line.rstrip())
-
-def sendKeystring(keystr,LYX_PID):
-       print "sending keystring "+keystr+"\n"
-       if not re.match(".*\w.*", keystr):
-               print ("print ."+keystr+".\n")
-               keystr="a"
-       os.system("while ( test -e /proc/$LYX_PID/status && ! grep 'tate.*[(]sleeping[)]' /proc/$LYX_PID/status); do echo -n . ; sleep 0.02; done")
-       cmd="xvkbd -xsendevent -text '"+keystr+"';sleep 0.03"
-       sys.stdout.flush()
-        os.system(cmd)
-       sys.stdout.flush()
+
+    def __init__(self, filename, p):
+
+        self.infile = open(filename, 'r')
+        self.lines = self.infile.readlines()
+        self.infile.close()
+        linesbak = self.lines
+        self.p = p
+        print p, self.p, 'self.p'
+        self.i = 0
+        self.count = 0
+        self.loops = 0
+
+        # Now we start randomly dropping lines, which we hope are redundant
+        # p is the probability that any given line will be removed
+
+        if p > 0.001:
+            if random.uniform(0, 1) < 0.5:
+                print 'randomdrop_independant\n'
+                self.randomdrop_independant()
+            else:
+                print 'randomdrop_slice\n'
+                self.randomdrop_slice()
+        if screenshot_out is None:
+            count_atleast = 100
+        else:
+            count_atleast = 1
+        self.max_count = max(len(self.lines) + 20, count_atleast)
+        if len(self.lines) < 1:
+            self.lines = linesbak
+
+    def randomdrop_independant(self):
+        p = self.p
+
+        # The next couple of lines are to ensure that at least one line is dropped
+
+        drop = random.randint(0, len(self.lines) - 1)
+        del self.lines[drop]
+        p = p - 1 / len(self.lines)
+        origlines = self.lines
+        self.lines = []
+        for l in origlines:
+            if random.uniform(0, 1) < self.p:
+                print 'Randomly dropping line ' + l + '\n'
+            else:
+                self.lines.append(l)
+        print 'LINES\n'
+        print self.lines
+        sys.stdout.flush()
+
+    def randomdrop_slice(self):
+        lines = self.lines
+        if random.uniform(0, 1) < 0.4:
+            lines.append(lines[0])
+            del lines[0]
+        num_lines = len(lines)
+        max_drop = max(5, num_lines / 5)
+        num_drop = random.randint(1, 5)
+        drop_mid = random.randint(0, num_lines)
+        drop_start = max(drop_mid - num_drop / 2, 0)
+        drop_end = min(drop_start + num_drop, num_lines)
+        print drop_start, drop_mid, drop_end
+        print lines
+        del lines[drop_start:drop_end]
+        print lines
+        self.lines = lines
+
+    def getCommand(self):
+        if self.count >= self.max_count:
+            os._exit(0)
+        if self.i >= len(self.lines):
+            self.loops = self.loops + 1
+            self.i = 0
+            return 'Loop'
+        line = self.lines[self.i]
+        self.count = self.count + 1
+        self.i = self.i + 1
+        print 'Line read: <<' + line + '>>\n'
+        return line.rstrip('\n').rstrip()
+
+
+def lyx_sleeping():
+    fname = '/proc/' + lyx_pid + '/status'
+    if not os.path.exists(fname):
+        return False
+    f = open(fname, 'r')
+    lines = f.readlines()
+    sleeping = lines[1].find('(sleeping)') > 0
+
+    # print 'LYX_STATE', lines[1] , 'SLEEPING=', sleeping
+
+    return sleeping
+
+
+def sendKeystring(keystr, LYX_PID):
+
+    # print "sending keystring "+keystr+"\n"
+
+    if not re.match(".*\w.*", keystr):
+        print 'print .' + keystr + '.\n'
+        keystr = 'a'
+    before_secs = time.time()
+    while not lyx_sleeping():
+        time.sleep(0.02)
+        print '.',
+        if time.time() - before_secs > 180:
+            print 'Killing due to freeze (KILL_FREEZE)'
+
+            # Do profiling, but sysprof has no command line interface?
+            # os.system("killall -KILL lyx")
+
+            os._exit(1)
+    if not screenshot_out is None:
+        while not lyx_sleeping():
+            time.sleep(0.02)
+            print '.',
+        print 'Making Screenshot: ' + screenshot_out
+        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 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")
-       
-                       
-lyx_pid=os.environ.get("LYX_PID")
-print("lyx_pid: "+lyx_pid+"\n");
-infilename=os.environ.get("KEYTEST_INFILE")
-outfilename=os.environ.get("KEYTEST_OUTFILE")
-max_drop=os.environ.get("MAX_DROP")
-lyx_window_name=os.environ.get("LYX_WINDOW_NAME");
-
-file_new_command=os.environ.get("FILE_NEW_COMMAND");
+    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")
+
+
+lyx_pid = os.environ.get('LYX_PID')
+print 'lyx_pid: ' + lyx_pid + '\n'
+infilename = os.environ.get('KEYTEST_INFILE')
+outfilename = os.environ.get('KEYTEST_OUTFILE')
+max_drop = os.environ.get('MAX_DROP')
+lyx_window_name = os.environ.get('LYX_WINDOW_NAME')
+screenshot_out = os.environ.get('SCREENSHOT_OUT')
+
+file_new_command = os.environ.get('FILE_NEW_COMMAND')
 if file_new_command is None:
-       file_new_command="\Afn"
+    file_new_command = "\Afn"
 
-ResetCommand=os.environ.get("RESET_COMMAND");
+ResetCommand = os.environ.get('RESET_COMMAND')
 if ResetCommand is None:
-       ResetCommand="\[Escape]\[Escape]\[Escape]\[Escape]"+file_new_command
-       #ResetCommand="\[Escape]\[Escape]\[Escape]\[Escape]\Cw\Cw\Cw\Cw\Cw\Afn"
+    ResetCommand = "\[Escape]\[Escape]\[Escape]\[Escape]" + file_new_command
+    #ResetCommand="\[Escape]\[Escape]\[Escape]\[Escape]\Cw\Cw\Cw\Cw\Cw\Afn"
 
 if lyx_window_name is None:
-       lyx_window_name="LyX";
+    lyx_window_name = 'LyX'
 
-print("outfilename: "+outfilename+"\n")
-print("max_drop: "+max_drop+"\n")
+print 'outfilename: ' + outfilename + '\n'
+print 'max_drop: ' + max_drop + '\n'
 
 if infilename is None:
-       print("infilename is None\n")
-       x=CommandSource()
-       print ("Using x=CommandSource\n");
+    print 'infilename is None\n'
+    x = CommandSource()
+    print 'Using x=CommandSource\n'
 else:
-       print("infilename: "+infilename+"\n")
-       probability_we_drop_a_command=random.uniform(0,float(max_drop))
-       print ("probability_we_drop_a_command: ")
-       print '%s'%(probability_we_drop_a_command)
-       print  "\n"
-       x=CommandSourceFromFile(infilename,probability_we_drop_a_command)
-       print ("Using x=CommandSourceFromFile\n");
+    print 'infilename: ' + infilename + '\n'
+    probability_we_drop_a_command = random.uniform(0, float(max_drop))
+    print 'probability_we_drop_a_command: '
+    print '%s' % probability_we_drop_a_command
+    print '\n'
+    x = CommandSourceFromFile(infilename, probability_we_drop_a_command)
+    print 'Using x=CommandSourceFromFile\n'
 
-outfile=open(outfilename,'w')
+outfile = open(outfilename, 'w')
 
 RaiseWindow()
-sendKeystring("\Afn",lyx_pid)
-write_commands=True;
+sendKeystring("\Afn", lyx_pid)
+write_commands = True
 
 while True:
-       os.system("echo -n LOADAVG:; cat /proc/loadavg")
-       c=x.getCommand()
-       if (c=="Loop"):
-               outfile.close()
-               outfile=open(outfilename+'+','w')
-               print ("Now Looping")
-       outfile.writelines(c+'\n')
-       outfile.flush()
-       if c=="RaiseLyx":
-               print ("Raising Lyx");
-               RaiseWindow()
-       elif c[0:4]=="KK: ":
-               if os.path.exists("/proc/"+lyx_pid+"/status"):
-                       sendKeystring(c[4:],lyx_pid)
-               else:
-                       os.system("killall lyx; sleep 2 ; killall -9 lyx")
-                       print ("No path /proc/"+lyx_pid+"/status, exiting")
-                       os._exit(1)
-       elif (c=="Loop"):
-               RaiseWindow()
-               sendKeystring(ResetCommand,lyx_pid)
-       else:
-               print ("Unrecognised Command '"+c+"'\n")
+    os.system('echo -n LOADAVG:; cat /proc/loadavg')
+    c = x.getCommand()
+    if c == 'Loop':
+        outfile.close()
+        outfile = open(outfilename + '+', 'w')
+        print 'Now Looping'
+    outfile.writelines(c + '\n')
+    outfile.flush()
+    if c == 'RaiseLyx':
+        print 'Raising Lyx'
+        RaiseWindow()
+    elif c[0:4] == 'KK: ':
+        if os.path.exists('/proc/' + lyx_pid + '/status'):
+            sendKeystring(c[4:], lyx_pid)
+        else:
+            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: ':
+        DELAY = c[4:].rstrip('\n')
+        print 'Setting DELAY to ' + DELAY + '.'
+    elif c == 'Loop':
+        RaiseWindow()
+        sendKeystring(ResetCommand, lyx_pid)
+    else:
+        print "Unrecognised Command '" + c + "'\n"
index 9390c9510b717debdbb6ed46a7757b33b77ec54a..5f5a186980ff50e2444b5d9eb1316fcbad040fa6 100755 (executable)
@@ -1,11 +1,15 @@
-AUTOLYX=`ps gaux | grep autolyx | grep -v grep | sed 's/[^ ]* //' | sed s/0.0.*//g`
-TESTPY=`ps gaux | grep test.py | grep -v grep | sed 's/[^ ]* //' | sed s/0.0.*//g`
+#!/bin/sh
+KT=`dirname "$0"`
+AUTOLYX=`ps gux "-u$USER" | grep autolyx | grep -v grep | sed 's/[^ ]* //' | sed s/0.0.*//g`
+TESTPY=`ps gux "-u$USER" | grep test.py | grep -v grep | sed 's/[^ ]* //' | sed s/0.0.*//g`
+
 killall autolyx
 killall test.py
 killall lyx
 killall gdb
 killall xterm
 killall replay.sh
+killall xclip
 kill $AUTOLYX $TESTPY
 sleep 0.3
 killall autolyx -9
@@ -14,4 +18,7 @@ killall lyx -9
 killall gdb -9
 killall xterm -9
 killall replay.sh -9
+killall xclip -9
+$KT/killall_p reproduce
+$KT/killall_p doNtimes
 kill $AUTOLYX $TESTPY -9
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/development/keystest/list_all_children.sh b/development/keystest/list_all_children.sh
new file mode 100755 (executable)
index 0000000..11359ae
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+listall () {
+PID_LIST="$*"
+while [ ! -z "$PID_LIST" ]
+do
+       #PID_LIST=`ps -o pid=  --ppid "$PID_LIST"| sed 's/^ *//g'` 
+       PID_LIST=`ps -o pid=  --ppid "$PID_LIST"` 
+       PID_LIST=`echo $PID_LIST` 
+       #PID_LIST=`ps -o pid=  --ppid "$PID_LIST"` 
+       echo $PID_LIST
+done
+}
+
+kill_all_children () {
+       kill `listall "$*"`
+       sleep 0.1
+       kill -9 `listall "$*"`
+}
+
+if [ "$1"="$kill"  ]
+then
+       shift
+       kill_all_children "$*"
+else
+       listall "$*"
+fi
diff --git a/development/keystest/make_screenshot_html.py b/development/keystest/make_screenshot_html.py
new file mode 100755 (executable)
index 0000000..aed255b
--- /dev/null
@@ -0,0 +1,69 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import re
+import os
+import sys
+
+# sec="1250005988"
+# dir='.'
+
+# if len(sys.argv) > 1:
+
+wdir = sys.argv[1]
+sec = sys.argv[2]
+base_filename = sec + '.s'
+reGetNumber = re.compile(base_filename + '(\d*).png')
+
+largest_screenshot_number = -1
+
+for f in os.listdir(wdir):
+
+    # print f
+
+    m = reGetNumber.match(f)
+    if m:
+
+        # print f
+        # print m.groups(1)[0]
+
+        n = int(m.groups(1)[0])
+        largest_screenshot_number = max(largest_screenshot_number, n)
+
+# print largest_screenshot_number
+
+keycodes = ['', 'KK: \Afn']
+keycodes.extend(open(wdir + '/' + sec + '.KEYCODEpure'))
+keycodes.extend(open(wdir + '/' + sec + '.KEYCODEpure+'))
+
+
+def Highlight_Keycode_i(keycodes, i):
+    s = ''
+    for (j, k) in enumerate(keycodes):
+
+        # print k
+
+        if k[0:4] == 'KK: ':
+            k = k[4:]
+        if j == i:
+            s = s + '<b>' + k + '</b>'
+        else:
+            s = s + k
+    return s
+
+
+print '<html>'
+print '<title>Keytest Screenshots</title>'
+for i in range(1, largest_screenshot_number + 1):
+#for (i,k) in enumerate(keycodes)[1:]:
+    k = keycodes[i]
+    print '<a name='+str(i)+'></a>',
+    print '<a href="#0">|&lt;</a> <a href="#'+str(max(i-1, 0))+'">&lt;&lt;</a>',
+    print '<a href="#'+str(i+1)+'">&gt;&gt;</a>',
+    print '<a href="#'+str(largest_screenshot_number)+'">&gt;|</a>',
+    #print k.strip(),
+    print Highlight_Keycode_i(keycodes, i),
+    print '<br><img src="'+sec+'.s'+str(i)+'.png"><br>'
+for k in keycodes[largest_screenshot_number+1:]:
+    print k+'<br>'
+print '<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>'
+#print '</html>'
\ No newline at end of file
index a1bbf72ce35db626380fd7cb998b8d74da2260ae..0940c0606df6e18d8dd99b7ab4cd5c10c28ae78b 100755 (executable)
@@ -1,28 +1,18 @@
 #!/bin/bash
-LT=development/keystest
+#LT=development/keystest
+LT=`dirname $0`
 
 GEOM=320x200
-convert -normalize -scale $GEOM -quality $QUALITY $f $GEOM/$f
-
-UNIQUE_LINE=1
-SRC=
-
-
-if [ -e out/log ]
-then   
-   LT=.
+QUALITY=85
+if [ -z "$KEYCODE_DIR" ]
+then
+       KEYCODE_DIR=out
 fi
+#convert -normalize -scale $GEOM -quality $QUALITY $f $GEOM/$f
 
-while [ ! -e $LT/out/log ]
-do
-  cd ..
-  if [ `pwd` = '/' ]
-  then
-     exit
-  fi
-done
+UNIQUE_LINE=1
 
-OUT=$LT/out/html
+OUT=$LT/out/html4
 mkdir -p $OUT
 rm $OUT/index*.html
 ls $OUT/*.html
@@ -46,7 +36,7 @@ do
        then
                echo -n '\[!Loop]'
        else
-               echo -n "$k" | sed s/^KK:\ //
+               echo -n "$k" | sed 's/^KK: //'
        fi
 done
 }
@@ -55,24 +45,33 @@ html_keycode() {
          cat "$f_base.KEYCODEpure" | tidy_keycode 
          echo -n '<font color=gray>'
          cat "$f_base.KEYCODEpure+" | tidy_keycode 
-         echo -n '</font><br/>'
+         echo -n '</font>'
+
 }
 
 gdb2html() {
+echo g $g
 cat $g | sed 's/&/&amp/g' | sed 's/</&lt/g'  | while read -r l
 do
+       #c=`echo $l | grep -i -o "at [[:alnum:]./]*:[0-9]*"`
+       #We may want to support slashes later, but we'd have to support browsing
+       #Qt source for that to be useful for LyX
        c=`echo $l | grep -i -o "at [[:alnum:].]*:[0-9]*"`
        if [ -z "$c" ]
        then
                echo -- "$l" | sed s/--//
        else
-               cpp=`echo "$c" | sed s/at\ // | sed s/:.*//g`
-               lineno=`echo "$c" | sed s/.*://g`
+               cpp=`echo "$c" | sed 's/at //' | sed 's/:.*//g'`
+               #cpp=`basename $cpp`
+               echo cpp $cpp
+               lineno=`echo "$c" | sed 's/.*://g'`
                echo $cpp,$lineno 1>&2
                #if [ -e "$CPP_HTML_DIR/$cpp.html" ]
                if true
                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>?"
                else
                        echo "$l"
                fi
@@ -80,12 +79,24 @@ do
 done | sed 's/^/<br\/>/'
 }
 
-for file in `find $LT/out/ | grep replay/last_crash_sec`
+echo beginning
+#for file in `find $LT/out/ -anewer $LT/out/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$`
 do
- echo last_crash_sec file: $file
- SEC=`cat $file`
+ lcs_file=`echo $file | sed 's/save\/.*//g'`last_crash_sec
+ echo last_crash_sec file: $lcs_file
+ SEC2=`cat $lcs_file`
+ SEC=`basename $file | sed s/[.].*$//g`
+ echo SEC .$SEC. .$SEC2.
+ #if [ ! $SEC -eq $SEC2 ]
+ #then
+       #break
+ #fi
  echo SEC $SEC
- f_base=`echo $file | sed s/last_crash_sec/$SEC/g`
+ #f_base=`echo $file | sed s/last_crash_sec/$SEC/g`
+ f_base=`dirname $file`'/'$SEC
+ echo f_base $f_base
  NUM_KEYCODES=`wc -l < "$f_base.KEYCODEpure"`
  echo NUM_KEYCODES=$NUM_KEYCODES...
  if [ "$NUM_KEYCODES" -lt 80 ]  
@@ -94,7 +105,6 @@ do
   f=$f_base.GDB
   echo $f
   g=$f.short
-  #if 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])' -A9999  <$f >$g
   if true
   then
@@ -109,13 +119,22 @@ do
        echo '<html>' >> $LT/out/$INDEX
        echo -n "<a href=\"$SEC.html\">$TITLE</a> " >> $OUT/indexreport.html
        html_keycode >> $OUT/indexreport.html
+       if ls $f_base.s*.png 
+       then
+               echo -n "<a href=\"$SEC.screenshot.html\">screenshots</a>" >> $OUT/indexreport.html
+       fi
+       echo -n '<br/> '>> $OUT/indexreport.html
        echo >> $OUT/indexreport.html
+       echo -n '<br> '>> $LT/out/$INDEX
+       echo >> $LT/out/$INDEX
+
        ( echo '<html>'
          echo "<h1>$TITLE</h1>"
          html_keycode
          echo "<a href=$SEC.KEYCODE>KEYCODES</a> "
-         echo "<a href=$SEC.GDB>GDB</a><br/>"
-         echo "<a href=$SEC.GDB.png><img src=$SEC.small.png/></a><br/><br/>"
+         echo "<a href=$SEC.GDB>GDB</a>"
+         #echo "<a href=$SEC.GDB.png><img src=$SEC.small.png/></a><br/><br/>"
+         echo "<a href=$SEC.screenshot.html><img src=$SEC.small.png/></a><br/><br/>"
          gdb2html
        ) > $OUT/$SEC.html
        echo '<a href="'"$SEC.html"'">'$SEC'</a><br/>' >> $OUT/$INDEX
@@ -124,8 +143,12 @@ do
        then  
                convert -normalize -scale $GEOM $f.png $OUT/$SEC.small.png -quality 85
        fi
-       chmod a+r $f $f.png $f_base.KEYCODE $f_base.html $OUT/indexreport.html
-       ln $f $f.png $f_base.KEYCODE $f_base.html $OUT/
+       chmod a+r $f $f.png $f_base.KEYCODE* $f_base.html $OUT/indexreport.html
+       ln $f $f.png $f_base.KEYCODE* $f_base.html $f_base.s*.png  $OUT/
+       if ls $f_base.s*.png 
+       then
+               $LT/make_screenshot_html.py $OUT $SEC > $OUT/$SEC.screenshot.html
+       fi
   fi
  fi
 done
@@ -134,5 +157,4 @@ echo "<html>" >> $OUT/indexreport.html
 echo "<h1>List of bugs found</h1>" >> $OUT/indexreport.html
 sort -k 2 -t '>' < $OUT/indexreport.html.bak >> $OUT/indexreport.html
 
-$OUT/
-exit
+firefox $OUT/indexreport.html
index 4b1501e44979fa37d70a31bafbbc8f42116af3a1..150f77ab434af0b66db2306f27567cc45774eedc 100755 (executable)
@@ -8,9 +8,23 @@ echo $LATEST_FILE | (
        ls out/* -lotd | head
  )
 )
-ls out/* -tdo -1 | grep replay  
+ls out/* -tdo -1 | grep replay |head -n4
 
 LATEST_FILE=`ls out/* -td -1 | grep replay  | head -n1`
+if  [ $LATEST_FILE = "out/toreplay" ]
+then
+       #echo foo
+       LATEST_FILE=`ls out/toreplay/* -td -1 | grep replay  | head -n1`        
+fi
+
+if  [ $LATEST_FILE = "out/toreplay/replayed" ]
+then
+       echo foo
+       LATEST_FILE=`ls out/toreplay/replayed/* -td -1 | grep replay  | head -n1`       
+else
+       echo oof
+fi
+
 echo  LATEST_FILE $LATEST_FILE 
 echo $LATEST_FILE | (
  grep replay > /dev/null && (
@@ -19,12 +33,12 @@ echo $LATEST_FILE | (
        ls $LATEST_FILE/*re -lotd | head
        SEC=`cat $LATEST_FILE/last_crash_sec`
        echo $SEC $(($NOW_SEC-$SEC))
-       ls -l $LATEST_FILE/$SEC.KEYCODEpure
+       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
   else
        ls $LATEST_FILE -lot | head
-       cat `echo $LATEST_FILE | sed s/KEYCODEpure.replay/GDB/` | grep "signal SIG" -A 9
+       cat `echo $LATEST_FILE | sed s/KEYCODEpure.replay/GDB/` | grep "signal SIG" -A 29
   fi
        cat $LATEST_FILE/log | grep Bore | tail -n2
  ) || (
@@ -38,10 +52,10 @@ Trace
 reproduced
 X_PID
 x-session" out/log | grep -v kill | grep -v Terminated | tail -n 9
-exit
+#exit
 echo autolyx crashes ---------
 grep autolyx: out/log | grep -v kill | grep -v Terminated #-A 5
 echo python crashes ---------
-grep -i Trace out/log -A 5
-echo misc ----
-grep reproduced out/log | tail -n5
+grep -i -a Trace out/log -A 7 | tail -n8
+#echo misc ----
+#grep reproduced out/log | tail -n5