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