tests/xvfb-run
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Jul 16 11:07:18 2016 +0100 (2016-07-16)
changeset 61 31fb35727621
permissions -rwxr-xr-x
Support parallel installations. The idea is that for CAD screener, we want
to be able to install this on the same machine as a standard AVOT setup
(most notably for John's laptop). To allow for the possibility of a second
application that might have the same requirements, we add the concept of
vendor-specific distributions. Thus we can have one distribution for CAD
screener and one for The Next Big Thing. It doesn't seem trivial to have
both CAD screener and AVOT under the same vendor tag so we'll have to have
AVOT under "City Occupational" and CAD screener under "City Occupational Ltd"
or some such kludge.

Most of this is done although we are very short of test cases (in particular
we don't test that it's actually possible to install CAD screener in parallel
with AVOT or to update either of them once installed, which is fundamental).

We also have a lot of baggage left over, including an intercept of razor_set.
The problem that this was introduced to debug has been fixed but it looks
like there are a number of memory leaks which it might be useful to help
track down so it has been left in place for now.

There is still a lot of confusion in plover between path-based and URI-based
API. We should review the API, decide what we want and have a general clear up.

There is also confusion as to the purpose of RAZOR_ROOT (and meaning; path or
URI). This is not used at all in librazor (although it is used in razor.exe).
Ideally we shouldn't use it in plover or plover-gtk either although again, we
might want to support it or an equivalent in (some of) the various executables.

Work that would still to nice to do for CAD screener:

- uninstall (ideally as an installed program that hooks into Add/Remove programs
but even re-running the installer would be acceptable).
- xz support (smaller packages).
- repomd.xml and xml:base (would be needed for an Internet installer).
- graphical installer.
     1 #!/bin/sh
     2 
     3 # This script starts an instance of Xvfb, the "fake" X server, runs a command
     4 # with that server available, and kills the X server when done.  The return
     5 # value of the command becomes the return value of this script.
     6 #
     7 # If anyone is using this to build a Debian package, make sure the package
     8 # Build-Depends on xvfb and xauth.
     9 
    10 set -e
    11 
    12 PROGNAME=xvfb-run
    13 SERVERNUM=99
    14 AUTHFILE=
    15 ERRORFILE=/dev/null
    16 XVFBARGS="-screen 0 640x480x8"
    17 LISTENTCP="-nolisten tcp"
    18 XAUTHPROTO=.
    19 
    20 # Query the terminal to establish a default number of columns to use for
    21 # displaying messages to the user.  This is used only as a fallback in the event
    22 # the COLUMNS variable is not set.  ($COLUMNS can react to SIGWINCH while the
    23 # script is running, and this cannot, only being calculated once.)
    24 DEFCOLUMNS=$(stty size 2>/dev/null | awk '{print $2}') || true
    25 if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" >/dev/null 2>&1; then
    26     DEFCOLUMNS=80
    27 fi
    28 
    29 # Display a message, wrapping lines at the terminal width.
    30 message () {
    31     echo "$PROGNAME: $*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS}
    32 }
    33 
    34 # Display an error message.
    35 error () {
    36     message "error: $*" >&2
    37 }
    38 
    39 # Display a usage message.
    40 usage () {
    41     if [ -n "$*" ]; then
    42         message "usage error: $*"
    43     fi
    44     cat <<EOF
    45 Usage: $PROGNAME [OPTION ...] COMMAND
    46 Run COMMAND (usually an X client) in a virtual X server environment.
    47 Options:
    48 -a        --auto-servernum          try to get a free server number, starting at
    49                                     --server-num
    50 -e FILE   --error-file=FILE         file used to store xauth errors and Xvfb
    51                                     output (default: $ERRORFILE)
    52 -f FILE   --auth-file=FILE          file used to store auth cookie
    53                                     (default: ./.Xauthority)
    54 -h        --help                    display this usage message and exit
    55 -n NUM    --server-num=NUM          server number to use (default: $SERVERNUM)
    56 -l        --listen-tcp              enable TCP port listening in the X server
    57 -p PROTO  --xauth-protocol=PROTO    X authority protocol name to use
    58                                     (default: xauth command's default)
    59 -s ARGS   --server-args=ARGS        arguments (other than server number and
    60                                     "-nolisten tcp") to pass to the Xvfb server
    61                                     (default: "$XVFBARGS")
    62 EOF
    63 }
    64 
    65 # Find a free server number by looking at .X*-lock files in /tmp.
    66 find_free_servernum() {
    67     # Sadly, the "local" keyword is not POSIX.  Leave the next line commented in
    68     # the hope Debian Policy eventually changes to allow it in /bin/sh scripts
    69     # anyway.
    70     #local i
    71 
    72     i=$SERVERNUM
    73     while [ -f /tmp/.X$i-lock ]; do
    74         i=$(($i + 1))
    75     done
    76     echo $i
    77 }
    78 
    79 # Clean up files
    80 clean_up() {
    81     if [ -e "$AUTHFILE" ]; then
    82         XAUTHORITY=$AUTHFILE xauth remove ":$SERVERNUM" >>"$ERRORFILE" 2>&1
    83     fi
    84     if [ -n "$XVFB_RUN_TMPDIR" ]; then
    85         if ! rm -r "$XVFB_RUN_TMPDIR"; then
    86             error "problem while cleaning up temporary directory"
    87             exit 5
    88         fi
    89     fi
    90     if [ -n "$XVFBPID" ]; then
    91         kill "$XVFBPID" >>"$ERRORFILE" 2>&1
    92     fi
    93 }
    94 
    95 # Parse the command line.
    96 ARGS=$(getopt --options +ae:f:hn:lp:s:w: \
    97        --long auto-servernum,error-file:,auth-file:,help,server-num:,listen-tcp,xauth-protocol:,server-args:,wait: \
    98        --name "$PROGNAME" -- "$@")
    99 GETOPT_STATUS=$?
   100 
   101 if [ $GETOPT_STATUS -ne 0 ]; then
   102     error "internal error; getopt exited with status $GETOPT_STATUS"
   103     exit 6
   104 fi
   105 
   106 eval set -- "$ARGS"
   107 
   108 while :; do
   109     case "$1" in
   110         -a|--auto-servernum) SERVERNUM=$(find_free_servernum); AUTONUM="yes" ;;
   111         -e|--error-file) ERRORFILE="$2"; shift ;;
   112         -f|--auth-file) AUTHFILE="$2"; shift ;;
   113         -h|--help) SHOWHELP="yes" ;;
   114         -n|--server-num) SERVERNUM="$2"; shift ;;
   115         -l|--listen-tcp) LISTENTCP="" ;;
   116         -p|--xauth-protocol) XAUTHPROTO="$2"; shift ;;
   117         -s|--server-args) XVFBARGS="$2"; shift ;;
   118         -w|--wait) shift ;;
   119         --) shift; break ;;
   120         *) error "internal error; getopt permitted \"$1\" unexpectedly"
   121            exit 6
   122            ;;
   123     esac
   124     shift
   125 done
   126 
   127 if [ "$SHOWHELP" ]; then
   128     usage
   129     exit 0
   130 fi
   131 
   132 if [ -z "$*" ]; then
   133     usage "need a command to run" >&2
   134     exit 2
   135 fi
   136 
   137 if ! which xauth >/dev/null; then
   138     error "xauth command not found"
   139     exit 3
   140 fi
   141 
   142 # tidy up after ourselves
   143 trap clean_up EXIT
   144 
   145 # If the user did not specify an X authorization file to use, set up a temporary
   146 # directory to house one.
   147 if [ -z "$AUTHFILE" ]; then
   148     XVFB_RUN_TMPDIR="$(mktemp -d -t $PROGNAME.XXXXXX)"
   149     # Create empty file to avoid xauth warning
   150     AUTHFILE=$(tempfile -n "$XVFB_RUN_TMPDIR/Xauthority")
   151 fi
   152 
   153 # Start Xvfb.
   154 MCOOKIE=$(mcookie)
   155 tries=10
   156 while [ $tries -gt 0 ]; do
   157     tries=$(( $tries - 1 ))
   158     XAUTHORITY=$AUTHFILE xauth source - << EOF >>"$ERRORFILE" 2>&1
   159 add :$SERVERNUM $XAUTHPROTO $MCOOKIE
   160 EOF
   161     # handle SIGUSR1 so Xvfb knows to send a signal when it's ready to accept
   162     # connections
   163     trap : USR1
   164     (trap '' USR1; exec Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP -auth $AUTHFILE >>"$ERRORFILE" 2>&1) &
   165     XVFBPID=$!
   166 
   167     wait || :
   168     if kill -0 $XVFBPID 2>/dev/null; then
   169         break
   170     elif [ -n "$AUTONUM" ]; then
   171         # The display is in use so try another one (if '-a' was specified).
   172         SERVERNUM=$((SERVERNUM + 1))
   173         SERVERNUM=$(find_free_servernum)
   174         continue
   175     fi
   176     error "Xvfb failed to start" >&2
   177     XVFBPID=
   178     exit 1
   179 done
   180 
   181 # Start the command and save its exit status.
   182 set +e
   183 DISPLAY=:$SERVERNUM XAUTHORITY=$AUTHFILE "$@" 2>&1
   184 RETVAL=$?
   185 set -e
   186 
   187 # Return the executed command's exit status.
   188 exit $RETVAL
   189 
   190 # vim:set ai et sts=4 sw=4 tw=80: