# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Name: virtualX.sh - part of the BeakerLib project
# Description: Helpers for handling virtual X server
#
# Author: Jan Hutar <jhutar@redhat.com>
# Author: Petr Splichal <psplicha@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2008-2010 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head1 NAME
BeakerLib - virtualX - Helpers for handling virtual X server
=head1 DESCRIPTION
This module provides a simple way to start and stop virtual X server
(framebuffer).
=head1 FUNCTIONS
=cut
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Internal Stuff
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Files:
#
# /tmp/$Xid-pid - contains PID for X server we are running # no-reboot
# /tmp/$Xid-display - contains DISPLAY of our X server # no-reboot
. $BEAKERLIB/testing.sh
. $BEAKERLIB/infrastructure.sh
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# rlVirtXGetCorrectID
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Generate internal ID from provided unique string, used by other
# rlVirtX* functions. You probably do not need to call this
# function and can forget about its existence.
#
# usage: rlVirtXGetCorrectID some_unique_string
#
# * some_unique_string: unique identifier, you can use e.g. $TEST
# (non-alnum chars will be stripped)
function rlVirtXGetCorrectID() {
echo "$1" | sed "s/[^[:alnum:]]//g"
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# rlVirtXGetPid
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Return PID of virtual X server
#
# usage: rlVirtXGetPid string
#
# * string: ID (e.g. $TEST variable can be used)
function rlVirtXGetPid() {
local Xid=$( rlVirtXGetCorrectID "$1" )
if [ -f "/tmp/$Xid-pid" ]; then # no-reboot
cat "/tmp/$Xid-pid" # no-reboot
else
return 1
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# rlVirtXStartDisplay
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Start a virtual X server on display "display"
#
# usage: rlVirtXStartDisplay string display
#
# * string: ID (e.g. $TEST variable can be used)
# * display: DISPLAY number (without ':')
function rlVirtXStartDisplay() {
local Xid=$( rlVirtXGetCorrectID "$1" )
local Xdisplay=$( echo $2 | sed "s/[^0-9]//g" )
rlLogDebug "rlVirtXStartDisplay: Starting a virtual X ($Xid) server on :$Xdisplay"
Xvfb :$Xdisplay -ac -screen 0 1600x1200x24 -fbdir /tmp & # no-reboot
local Xpid=$!
sleep 3
if ! ps | grep $Xpid >/dev/null; then
rlLogDebug "rlVirtXStartDisplay: Virtual X failed to start"
return 1
else
rlLogDebug "rlVirtXStartDisplay: Started with PID '$Xpid' on display :$Xdisplay"
echo "$Xpid" > /tmp/$Xid-pid # no-reboot
echo ":$Xdisplay" > /tmp/$Xid-display # no-reboot
return 0
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Virtual X Server --- Public Stuff
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head2 Virtual X Server
Functions providing simple way how to start and stop virtual X
server.
=cut
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# rlVirtualXStart
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head3 rlVirtualXStart
Start a virtual X server on a first free display. Tries only first
N displays, so you can run out of them.
rlVirtualXStart name
=over
=item name
String identifying the X server.
=back
Returns 0 when the server is started successfully.
=cut
function rlVirtualXStart() {
local Xmax=3
local Xid=$( rlVirtXGetCorrectID "$1" )
local Xdisplay=0
for Xdisplay in $( seq 1 $Xmax ); do
rlLogDebug "rlVirtualXStart: Trying to start on display :$Xdisplay"
if rlVirtXStartDisplay $Xid $Xdisplay; then
rlLogDebug "rlVirtualXStart: Started on display :$Xdisplay"
return 0
fi
done
rlLogDebug "rlVirtualXStart: Was not able to start on displays from :1 to :Xmax"
return 1
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# rlVirtualXGetDisplay
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head3 rlVirtualXGetDisplay
Get the DISPLAY variable for specified virtual X server.
rlVirtualXGetDisplay name
=over
=item name
String identifying the X server.
=back
Displays the number of display where specified virtual X server is
running to standard output. Returns 0 on success.
=cut
function rlVirtualXGetDisplay() {
local Xid=$( rlVirtXGetCorrectID "$1" )
if [ -f "/tmp/$Xid-display" ]; then # no-reboot
cat "/tmp/$Xid-display" # no-reboot
else
return 1
fi
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# rlVirtualXStop
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head3 rlVirtualXStop
Kill the specified X server.
rlVirtualXStop name
=over
=item name
String identifying the X server.
=back
Returns 0 when the server is stopped successfully.
=cut
function rlVirtualXStop() {
local Xid=$( rlVirtXGetCorrectID "$1" )
local Xpid=$( rlVirtXGetPid "$Xid" )
local Xdisplay=$( rlVirtualXGetDisplay "$1" )
if [ -z "$Xpid" ]; then
rlLogDebug "rlVirtualXStop: Provide pid you want to kill"
return 1
fi
if ps | grep $Xpid >/dev/null; then
kill "$Xpid"
fi
sleep 2; # added by koca (some servers aren't so quick :))
if ! ps | grep $Xpid >/dev/null; then
rlLogDebug "rlVirtualXStop: Normal 'kill $Xpid' succeed"
else
rlLogWarning "rlVirtualXStop: I had to 'kill -9 $Xpid' (rc: $?) X server"
kill -9 "$Xpid"
sleep 1
if [ -r "/tmp/.X$Xdisplay-lock" ]; then # no-reboot
rlLogDebug "rlVirtualXStop: Lock file '/tmp/.X$Xdisplay-lock' still exists, last attempt" # no-reboot
kill $( cat "/tmp/.X$Xdisplay-lock" ) &>/dev/null # no-reboot
kill -9 $( cat "/tmp/.X$Xdisplay-lock" ) &>/dev/null # no-reboot
rm -f "/tmp/.X$Xdisplay-lock" # no-reboot
sleep 1
fi
if ps | grep $Xpid >/dev/null; then
rlLogDebug "rlVirtualXStop: I was not able to kill pid '$Xpid', sorry"
return 2
fi
fi
rm -rf /tmp/$Xid-display /tmp/$Xid-pid # no-reboot
sleep 1 # give it some time to end
return 0
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Example
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head3 Example
Below is a simple example of usage. Note that a lot of usefull
debugging information is reported on the DEBUG level, so you can
run your test with C<DEBUG=1 make run> to get them.
rlVirtualXStart $TEST
rlAssert0 "Virtual X server started" $?
export DISPLAY="$( rlVirtualXGetDisplay $TEST )"
# ...your test which needs X...
rlVirtualXStop $TEST
rlAssert0 "Virtual X server killed" $?
These are "Requires" lines for your scripts - note different package
names for different RHEL versions:
@echo "Requires: xorg-x11-server-Xvfb" >> $(METADATA) # RHEL-5
@echo "Requires: xorg-x11-Xvfb" >> $(METADATA) # RHEL-4
@echo "Requires: XFree86-Xvfb" >> $(METADATA) # RHEL-3
=cut
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# AUTHORS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: <<'=cut'
=pod
=head1 AUTHORS
=over
=item *
Jan Hutar <jhutar@redhat.com>
=item *
Petr Splichal <psplicha@redhat.com>
=back
=cut