From 721b2e322aec36553360e1c277a2a133cafb9bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Sat, 27 Apr 2019 07:47:34 -0300 Subject: [PATCH 01/18] enable integration tests --- test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index f7a4580ae..d10004540 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,4 +2,4 @@ test: # For now integration tests don't work (lua-posix problems), skipping them - #$(MAKE) -C integration test + $(MAKE) -C integration test From f17e750b29a0dd1f96e2e7a50bf84627b3116f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Sat, 27 Apr 2019 07:55:03 -0300 Subject: [PATCH 02/18] Include system-autodetect in Makefile to find suitable LUA --- test/integration/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/integration/Makefile b/test/integration/Makefile index 31f859eb2..7961e4e48 100644 --- a/test/integration/Makefile +++ b/test/integration/Makefile @@ -1,3 +1,6 @@ +TOPDIR=../.. +include $(TOPDIR)/system-autodetect.mk + .PHONY: test libXinerama.so.1.0: Xinerama.c From 0e5f98965131758778da7168ecd0236bf66d2c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Sat, 27 Apr 2019 12:40:17 -0300 Subject: [PATCH 03/18] fix posix require --- test/integration/runtests.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index 6880ccc06..e374fdfd4 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -1,5 +1,5 @@ # on Debian in lua-posix -require "posix" +local posix = require "posix" function sleep(sec) os.execute("sleep " .. tonumber(sec)) From 173bd08a7126c715a10057494a01765210407fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Mon, 29 Apr 2019 10:44:02 -0300 Subject: [PATCH 04/18] Remove Xdummy, use Xorg's dummy driver --- test/integration/Xdummy | 1955 --------------------------------- test/integration/runtests.lua | 25 +- test/integration/xorg.conf | 64 ++ 3 files changed, 77 insertions(+), 1967 deletions(-) delete mode 100644 test/integration/Xdummy create mode 100644 test/integration/xorg.conf diff --git a/test/integration/Xdummy b/test/integration/Xdummy deleted file mode 100644 index 1da30f4c5..000000000 --- a/test/integration/Xdummy +++ /dev/null @@ -1,1955 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------- -# Copyright (C) 2005-2011 Karl J. Runge -# All rights reserved. -# -# This file is part of Xdummy. -# -# Xdummy is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or (at -# your option) any later version. -# -# Xdummy 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 Xdummy; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -# or see . -# ---------------------------------------------------------------------- -# -# -# Xdummy: an LD_PRELOAD hack to run a stock Xorg(1) or XFree86(1) server -# with the "dummy" video driver to make it avoid Linux VT switching, etc. -# -# Run "Xdummy -help" for more info. -# -install="" -uninstall="" -runit=1 -prconf="" -notweak="" -root="" -nosudo="" -xserver="" -geom="" -nomodelines="" -depth="" -debug="" -strace="" -cmdline_config="" - -PATH=$PATH:/bin:/usr/bin -export PATH - -program=`basename "$0"` - -help () { - ${PAGER:-more} << END -$program: - - A hack to run a stock Xorg(1) or XFree86(1) X server with the "dummy" - (RAM-only framebuffer) video driver such that it AVOIDS the Linux VT - switching, opening device files in /dev, keyboard and mouse conflicts, - and other problems associated with the normal use of "dummy". - - In other words, it tries to make Xorg/XFree86 with the "dummy" - device driver act more like Xvfb(1). - - The primary motivation for the Xdummy script is to provide a virtual X - server for x11vnc but with more features than Xvfb (or Xvnc); however - it could be used for other reasons (e.g. better automated testing - than with Xvfb.) One nice thing is the dummy server supports RANDR - dynamic resizing while Xvfb does not. - - So, for example, x11vnc+Xdummy terminal services are a little better - than x11vnc+Xvfb. - - To achieve this, while running the real Xserver $program intercepts - system and library calls via the LD_PRELOAD method and modifies - the behavior to make it work correctly (e.g. avoid the VT stuff.) - LD_PRELOAD tricks are usually "clever hacks" and so might not work - in all situations or break when something changes. - - WARNING: Take care in using Xdummy, although it never has it is - possible that it could damage hardware. One can use the -prconf - option to have it print out the xorg.conf config that it would use - and then inspect it carefully before actually using it. - - This program no longer needs to be run as root as of 12/2009. - However, if there are problems for certain situations (usually older - servers) it may perform better if run as root (use the -root option.) - When running as root remember the previous paragraph and that Xdummy - comes without any warranty. - - gcc/cc and other build tools are required for this script to be able - to compile the LD_PRELOAD shared object. Be sure they are installed - on the system. See -install and -uninstall described below. - - Your Linux distribution may not install the dummy driver by default, - e.g: - - /usr/lib/xorg/modules/drivers/dummy_drv.so - - some have it in a package named xserver-xorg-video-dummy you that - need to install. - -Usage: - - $program <${program}-args> - - (actually, the arguments can be supplied in any order.) - -Examples: - - $program -install - - $program :1 - - $program -debug :1 - - $program -tmpdir ~/mytmp :1 -nolisten tcp - -startx example: - - startx -e bash -- $program :2 -depth 16 - - (if startx needs to be run as root, you can su(1) to a normal - user in the bash shell and then launch ~/.xinitrc or ~/.xsession, - gnome-session, startkde, startxfce4, etc.) - -xdm example: - - xdm -config /usr/local/dummy/xdm-config -nodaemon - - where the xdm-config file has line: - - DisplayManager.servers: /usr/local/dummy/Xservers - - and /usr/local/dummy/Xservers has lines: - - :1 local /usr/local/dummy/Xdummy :1 -debug - :2 local /usr/local/dummy/Xdummy :2 -debug - - (-debug is optional) - -gdm/kdm example: - - TBD. - -Config file: - - If the file $program.cfg exists it will be sourced as shell - commands. Usually one will set some variables this way. - To disable sourcing, supply -nocfg or set XDUMMY_NOCFG=1. - -Root permission and x11vnc: - - Update: as of 12/2009 this program no longer must be run as root. - So try it as non-root before running it as root and/or the - following schemes. - - In some circumstances X server program may need to be run as root. - If so, one could run x11vnc as root with -unixpw (it switches - to the user that logs in) and that may be OK, some other ideas: - - - add this to sudo via visudo: - - ALL ALL = NOPASSWD: /usr/local/bin/Xdummy - - - use this little suid wrapper: -/* - * xdummy.c - * - cc -o ./xdummy xdummy.c - sudo cp ./xdummy /usr/local/bin/xdummy - sudo chown root:root /usr/local/bin/xdummy - sudo chmod u+s /usr/local/bin/xdummy - * - */ -#include -#include -#include -#include - -int main (int argc, char *argv[]) { - extern char **environ; - char str[100]; - sprintf(str, "XDUMMY_UID=%d", (int) getuid()); - putenv(str); - setuid(0); - setgid(0); - execv("/usr/local/bin/Xdummy", argv); - exit(1); - return 1; -} - - -Options: - - ${program}-args: - - -install Compile the LD_PRELOAD shared object and install it - next to the $program script file as: - - $0.so - - When that file exists it is used as the LD_PRELOAD - shared object without recompiling. Otherwise, - each time $program is run the LD_PRELOAD shared - object is compiled as a file in /tmp (or -tmpdir) - - If you set the environment variable - INTERPOSE_GETUID=1 when building, then when - $program is run as an ordinary user, the shared - object will interpose getuid() calls and pretend - to be root. Otherwise it doesn't pretend to - be root. - - You can also set the CFLAGS environment variable - to anything else you want on the compile cmdline. - - -uninstall Remove the file: - - $0.so - - The LD_PRELOAD shared object will then be compiled - each time this program is run. - - The X server is not started under -install, -uninstall, or -prconf. - - - :N The DISPLAY (e.g. :15) is often the first - argument. It is passed to the real X server and - also used by the Xdummy script as an identifier. - - -geom geom1[,geom2...] Take the geometry (e.g. 1024x768) or list - of geometries and insert them into the Screen - section of the tweaked X server config file. - Use this to have a different geometry than the - one(s) in the system config file. - - The option -geometry can be used instead of -geom; - x11vnc calls Xdummy and Xvfb this way. - - -nomodelines When you specify -geom/-geometry, $program will - create Modelines for each geometry and put them - in the Monitor section. If you do not want this - then supply -nomodelines. - - -depth n Use pixel color depth n (e.g. 8, 16, or 24). This - makes sure the X config file has a Screen.Display - subsection of this depth. Note this option is - ALSO passed to the X server. - - -DEPTH n Same as -depth, except not passed to X server. - - -tmpdir dir Specify a temporary directory, owned by you and - only writable by you. This is used in place of - /tmp/Xdummy.\$USER/.. to place the $program.so - shared object, tweaked config files, etc. - - -nonroot Run in non-root mode (working 12/2009, now default) - - -root Run as root (may still be needed in some - environments.) Same as XDUMMY_RUN_AS_ROOT=1. - - -nosudo Do not try to use sudo(1) when re-running as root, - use su(1) instead. - - -xserver path Specify the path to the Xserver to use. Default - is to try "Xorg" first and then "XFree86". If - those are not in \$PATH, it tries these locations: - /usr/bin/Xorg - /usr/X11R6/bin/Xorg - /usr/X11R6/bin/XFree86 - - -n Do not run the command to start the X server, - just show the command that $program would run. - The LD_PRELOAD shared object will be built, - if needed. Also note any XDUMMY* environment - variables that need to be set. - - -prconf Print, to stdout, the tweaked Xorg/XFree86 - config file (-config and -xf86config server - options, respectively.) The Xserver is not - started. - - -notweak Do not tweak (modify) the Xorg/XFree86 config file - (system or server command line) at all. The -geom - and similar config file modifications are ignored. - - It is up to you to make sure it is a working - config file (e.g. "dummy" driver, etc.) - Perhaps you want to use a file based on the - -prconf output. - - -nocfg Do not try to source $program.cfg even if it - exists. Same as setting XDUMMY_NOCFG=1. - - -debug Extra debugging output. - - -strace strace(1) the Xserver process (for troubleshooting.) - -ltrace ltrace(1) instead of strace (can be slow.) - - -h, -help Print out this help. - - - Xserver-args: - - Most of the Xorg and XFree86 options will work and are simply - passed along if you supply them. Important ones that may be - supplied if missing: - - :N X Display number for server to use. - - vtNN Linux virtual terminal (VT) to use (a VT is currently - still used, just not switched to and from.) - - -config file Driver "dummy" tweaked config file, a - -xf86config file number of settings are tweaked besides Driver. - - If -config/-xf86config is not given, the system one - (e.g. /etc/X11/xorg.conf) is used. If the system one cannot be - found, a built-in one is used. Any settings in the config file - that are not consistent with "dummy" mode will be overwritten - (unless -notweak is specified.) - - Use -config xdummy-builtin to force usage of the builtin config. - - If "file" is only a basename (e.g. "xorg.dummy.conf") with no /'s, - then no tweaking of it is done: the X server will look for that - basename via its normal search algorithm. If the found file does - not refer to the "dummy" driver, etc, then the X server will fail. - - You can set the env. var. XDUMMY_EXTRA_SERVER_ARGS to hold some - extra Xserver-args too. (Useful for cfg file.) - -Notes: - - The Xorg/XFree86 "dummy" driver is currently undocumented. It works - well in this mode, but it is evidently not intended for end-users. - So it could be removed or broken at any time. - - If the display Xserver-arg (e.g. :1) is not given, or ":" is given - that indicates $program should try to find a free one (based on - tcp ports.) - - If the display virtual terminal, VT, (e.g. vt9) is not given that - indicates $program should try to find a free one (or guess a high one.) - - This program is not completely secure WRT files in /tmp (but it tries - to a good degree.) Better is to use the -tmpdir option to supply a - directory only writable by you. Even better is to get rid of users - on the local machine you do not trust :-) - - Set XDUMMY_SET_XV=1 to turn on debugging output for this script. - -END -} - -warn() { - echo "$*" 1>&2 -} - -if [ "X$XDUMMY_SET_XV" != "X" ]; then - set -xv -fi - -if [ "X$XDUMMY_UID" = "X" ]; then - XDUMMY_UID=`id -u` - export XDUMMY_UID -fi -if [ "X$XDUMMY_UID" = "X0" ]; then - if [ "X$SUDO_UID" != "X" ]; then - XDUMMY_UID=$SUDO_UID - export XDUMMY_UID - fi -fi - -# check if root=1 first: -# -if [ "X$XDUMMY_RUN_AS_ROOT" = "X1" ]; then - root=1 -fi -for arg in $* -do - if [ "X$arg" = "X-nonroot" ]; then - root="" - elif [ "X$arg" = "X-root" ]; then - root=1 - elif [ "X$arg" = "X-nocfg" ]; then - XDUMMY_NOCFG=1 - export XDUMMY_NOCFG - fi -done - -if [ "X$XDUMMY_NOCFG" = "X" -a -f "$0.cfg" ]; then - . "$0.cfg" -fi - -# See if it really needs to be run as root: -# -if [ "X$XDUMMY_SU_EXEC" = "X" -a "X$root" = "X1" -a "X`id -u`" != "X0" ]; then - # this is to prevent infinite loop in case su/sudo doesn't work: - XDUMMY_SU_EXEC=1 - export XDUMMY_SU_EXEC - - dosu=1 - nosudo="" - - for arg in $* - do - if [ "X$arg" = "X-nonroot" ]; then - dosu="" - elif [ "X$arg" = "X-nosudo" ]; then - nosudo="1" - elif [ "X$arg" = "X-help" ]; then - dosu="" - elif [ "X$arg" = "X-h" ]; then - dosu="" - elif [ "X$arg" = "X-install" ]; then - dosu="" - elif [ "X$arg" = "X-uninstall" ]; then - dosu="" - elif [ "X$arg" = "X-n" ]; then - dosu="" - elif [ "X$arg" = "X-prconf" ]; then - dosu="" - fi - done - if [ $dosu ]; then - # we need to restart it with su/sudo: - if type sudo > /dev/null 2>&1; then - : - else - nosudo=1 - fi - if [ "X$nosudo" = "X" ]; then - warn "$program: supply the sudo password to restart as root:" - if [ "X$XDUMMY_UID" != "X" ]; then - exec sudo $0 -uid $XDUMMY_UID "$@" - else - exec sudo $0 "$@" - fi - else - warn "$program: supply the root password to restart as root:" - if [ "X$XDUMMY_UID" != "X" ]; then - exec su -c "$0 -uid $XDUMMY_UID $*" - else - exec su -c "$0 $*" - fi - fi - # DONE: - exit - fi -fi - -# This will hold the X display, e.g. :20 -# -disp="" -args="" -cmdline_config="" - -# Process Xdummy args: -# -while [ "X$1" != "X" ] -do - if [ "X$1" = "X-config" -o "X$1" = "X-xf86config" ]; then - cmdline_config="$2" - fi - case $1 in - ":"*) disp=$1 - ;; - "-install") install=1; runit="" - ;; - "-uninstall") uninstall=1; runit="" - ;; - "-n") runit="" - ;; - "-no") runit="" - ;; - "-norun") runit="" - ;; - "-prconf") prconf=1; runit="" - ;; - "-notweak") notweak=1 - ;; - "-noconf") notweak=1 - ;; - "-nonroot") root="" - ;; - "-root") root=1 - ;; - "-nosudo") nosudo=1 - ;; - "-xserver") xserver="$2"; shift - ;; - "-uid") XDUMMY_UID="$2"; shift - export XDUMMY_UID - ;; - "-geom") geom="$2"; shift - ;; - "-geometry") geom="$2"; shift - ;; - "-nomodelines") nomodelines=1 - ;; - "-depth") depth="$2"; args="$args -depth $2"; - shift - ;; - "-DEPTH") depth="$2"; shift - ;; - "-tmpdir") XDUMMY_TMPDIR="$2"; shift - ;; - "-debug") debug=1 - ;; - "-nocfg") : - ;; - "-nodebug") debug="" - ;; - "-strace") strace=1 - ;; - "-ltrace") strace=2 - ;; - "-h") help; exit 0 - ;; - "-help") help; exit 0 - ;; - *) args="$args $1" - ;; - esac - shift -done - -if [ "X$XDUMMY_EXTRA_SERVER_ARGS" != "X" ]; then - args="$args $XDUMMY_EXTRA_SERVER_ARGS" -fi - -# Try to get a username for use in our tmp directory, etc. -# -user="" -if [ X`id -u` = "X0" ]; then - user=root # this will also be used below for id=0 -elif [ "X$USER" != "X" ]; then - user=$USER -elif [ "X$LOGNAME" != "X" ]; then - user=$LOGNAME -fi - -# Keep trying... -# -if [ "X$user" = "X" ]; then - user=`whoami 2>/dev/null` -fi -if [ "X$user" = "X" ]; then - user=`basename "$HOME"` -fi -if [ "X$user" = "X" -o "X$user" = "X." ]; then - user="u$$" -fi - -if [ "X$debug" = "X1" -a "X$runit" != "X" ]; then - echo "" - echo "/usr/bin/env:" - env | egrep -v '^(LS_COLORS|TERMCAP)' | sort - echo "" -fi - -# Function to compile the LD_PRELOAD shared object: -# -make_so() { - # extract code embedded in this script into a tmp C file: - n1=`grep -n '^#code_begin' $0 | head -1 | awk -F: '{print $1}'` - n2=`grep -n '^#code_end' $0 | head -1 | awk -F: '{print $1}'` - n1=`expr $n1 + 1` - dn=`expr $n2 - $n1` - - tmp=$tdir/Xdummy.$RANDOM$$.c - rm -f $tmp - if [ -e $tmp -o -h $tmp ]; then - warn "$tmp still exists." - exit 1 - fi - touch $tmp || exit 1 - tail -n +$n1 $0 | head -n $dn > $tmp - - # compile it to Xdummy.so: - if [ -f "$SO" ]; then - mv $SO $SO.$$ - rm -f $SO.$$ - fi - rm -f $SO - touch $SO - if [ ! -f "$SO" ]; then - SO=$tdir/Xdummy.$user.so - warn "warning switching LD_PRELOAD shared object to: $SO" - fi - - if [ -f "$SO" ]; then - mv $SO $SO.$$ - rm -f $SO.$$ - fi - rm -f $SO - - # we assume gcc: - if [ "X$INTERPOSE_GETUID" = "X1" ]; then - CFLAGS="$CFLAGS -DINTERPOSE_GETUID" - fi - echo "$program:" cc -shared -fPIC $CFLAGS -o $SO $tmp - cc -shared -fPIC $CFLAGS -o $SO $tmp - rc=$? - rm -f $tmp - if [ $rc != 0 ]; then - warn "$program: cannot build $SO" - exit 1 - fi - if [ "X$debug" != "X" -o "X$install" != "X" ]; then - warn "$program: created $SO" - ls -l "$SO" - fi -} - -# Set tdir to tmp dir for make_so(): -if [ "X$XDUMMY_TMPDIR" != "X" ]; then - tdir=$XDUMMY_TMPDIR - mkdir -p $tdir -else - tdir="/tmp" -fi - -# Handle -install/-uninstall case: -SO=$0.so -if [ "X$install" != "X" -o "X$uninstall" != "X" ]; then - if [ -e "$SO" -o -h "$SO" ]; then - warn "$program: removing $SO" - fi - if [ -f "$SO" ]; then - mv $SO $SO.$$ - rm -f $SO.$$ - fi - rm -f $SO - if [ -e "$SO" -o -h "$SO" ]; then - warn "warning: $SO still exists." - exit 1 - fi - if [ $install ]; then - make_so - if [ ! -f "$SO" ]; then - exit 1 - fi - fi - exit 0 -fi - -# We need a tmp directory for the .so, tweaked config file, and for -# redirecting filenames we cannot create (under -nonroot) -# -tack="" -if [ "X$XDUMMY_TMPDIR" = "X" ]; then - XDUMMY_TMPDIR="/tmp/Xdummy.$user" - - # try to tack on a unique subdir (display number or pid) - # to allow multiple instances - # - if [ "X$disp" != "X" ]; then - t0=$disp - else - t0=$1 - fi - tack=`echo "$t0" | sed -e 's/^.*://'` - if echo "$tack" | grep '^[0-9][0-9]*$' > /dev/null; then - : - else - tack=$$ - fi - if [ "X$tack" != "X" ]; then - XDUMMY_TMPDIR="$XDUMMY_TMPDIR/$tack" - fi -fi - -tmp=$XDUMMY_TMPDIR -if echo "$tmp" | grep '^/tmp' > /dev/null; then - if [ "X$tmp" != "X/tmp" -a "X$tmp" != "X/tmp/" ]; then - # clean this subdir of /tmp out, otherwise leave it... - rm -rf $XDUMMY_TMPDIR - if [ -e $XDUMMY_TMPDIR ]; then - warn "$XDUMMY_TMPDIR still exists" - exit 1 - fi - fi -fi - -mkdir -p $XDUMMY_TMPDIR -chmod 700 $XDUMMY_TMPDIR -if [ "X$tack" != "X" ]; then - chmod 700 `dirname "$XDUMMY_TMPDIR"` 2>/dev/null -fi - -# See if we can write something there: -# -tfile="$XDUMMY_TMPDIR/test.file" -touch $tfile -if [ ! -f "$tfile" ]; then - XDUMMY_TMPDIR="/tmp/Xdummy.$$.$USER" - warn "warning: setting tmpdir to $XDUMMY_TMPDIR ..." - rm -rf $XDUMMY_TMPDIR || exit 1 - mkdir -p $XDUMMY_TMPDIR || exit 1 -fi -rm -f $tfile - -export XDUMMY_TMPDIR - -# Compile the LD_PRELOAD shared object if needed (needs XDUMMY_TMPDIR) -# -if [ ! -f "$SO" ]; then - SO="$XDUMMY_TMPDIR/Xdummy.so" - make_so -fi - -# Decide which X server to use: -# -if [ "X$xserver" = "X" ]; then - if type Xorg >/dev/null 2>&1; then - xserver="Xorg" - elif type XFree86 >/dev/null 2>&1; then - xserver="XFree86" - elif -x /usr/bin/Xorg; then - xserver="/usr/bin/Xorg" - elif -x /usr/X11R6/bin/Xorg; then - xserver="/usr/X11R6/bin/Xorg" - elif -x /usr/X11R6/bin/XFree86; then - xserver="/usr/X11R6/bin/XFree86" - fi - if [ "X$xserver" = "X" ]; then - # just let it fail below. - xserver="/usr/bin/Xorg" - warn "$program: cannot locate a stock Xserver... assuming $xserver" - fi -fi - -# See if the binary is suid or not readable under -nonroot mode: -# -if [ "X$BASH_VERSION" != "X" ]; then - xserver_path=`type -p $xserver 2>/dev/null` -else - xserver_path=`type $xserver 2>/dev/null | awk '{print $NF}'` -fi -if [ -e "$xserver_path" -a "X$root" = "X" -a "X$runit" != "X" ]; then - if [ ! -r $xserver_path -o -u $xserver_path -o -g $xserver_path ]; then - # XXX not quite correct with rm -rf $XDUMMY_TMPDIR ... - # we keep on a filesystem we know root can write to. - base=`basename "$xserver_path"` - new="/tmp/$base.$user.bin" - if [ -e $new ]; then - snew=`ls -l $new | awk '{print $5}' | grep '^[0-9][0-9]*$'` - sold=`ls -l $xserver_path | awk '{print $5}' | grep '^[0-9][0-9]*$'` - if [ "X$snew" != "X" -a "X$sold" != "X" -a "X$sold" != "X$snew" ]; then - warn "removing different sized copy:" - ls -l $new $xserver_path - rm -f $new - fi - fi - if [ ! -e $new -o ! -s $new ]; then - rm -f $new - touch $new || exit 1 - chmod 700 $new || exit 1 - if [ ! -r $xserver_path ]; then - warn "" - warn "NEED TO COPY UNREADABLE $xserver_path to $new as root:" - warn "" - ls -l $xserver_path 1>&2 - warn "" - warn "This only needs to be done once:" - warn " cat $xserver_path > $new" - warn "" - nos=$nosudo - if type sudo > /dev/null 2>&1; then - : - else - nos=1 - fi - if [ "X$nos" = "X1" ]; then - warn "Please supply root passwd to 'su -c'" - su -c "cat $xserver_path > $new" - else - warn "Please supply the sudo passwd if asked:" - sudo /bin/sh -c "cat $xserver_path > $new" - fi - else - warn "" - warn "COPYING SETUID $xserver_path to $new" - warn "" - ls -l $xserver_path 1>&2 - warn "" - cat $xserver_path > $new - fi - ls -l $new - if [ -s $new ]; then - : - else - rm -f $new - ls -l $new - exit 1 - fi - warn "" - warn "Please restart Xdummy now." - exit 0 - fi - if [ ! -O $new ]; then - warn "file \"$new\" not owned by us!" - ls -l $new - exit 1 - fi - xserver=$new - fi -fi - -# Work out display: -# -if [ "X$disp" != "X" ]; then - : -elif [ "X$1" != "X" ]; then - if echo "$1" | grep '^:[0-9]' > /dev/null; then - disp=$1 - shift - elif [ "X$1" = "X:" ]; then - # ":" means for us to find one. - shift - fi -fi -if [ "X$disp" = "X" -o "X$disp" = "X:" ]; then - # try to find an open display port: - # (tcp outdated...) - ports=`netstat -ant | grep LISTEN | awk '{print $4}' | sed -e 's/^.*://'` - n=0 - while [ $n -le 20 ] - do - port=`printf "60%02d" $n` - if echo "$ports" | grep "^${port}\$" > /dev/null; then - : - else - disp=":$n" - warn "$program: auto-selected DISPLAY $disp" - break - fi - n=`expr $n + 1` - done -fi - -# Work out which vt to use, try to find/guess an open one if necessary. -# -vt="" -for arg in $* -do - if echo "$arg" | grep '^vt' > /dev/null; then - vt=$arg - break - fi -done -if [ "X$vt" = "X" ]; then - if [ "X$user" = "Xroot" ]; then - # root can user fuser(1) to see if it is in use: - if type fuser >/dev/null 2>&1; then - # try /dev/tty17 thru /dev/tty32 - n=17 - while [ $n -le 32 ] - do - dev="/dev/tty$n" - if fuser $dev >/dev/null 2>&1; then - : - else - vt="vt$n" - warn "$program: auto-selected VT $vt => $dev" - break - fi - n=`expr $n + 1` - done - fi - fi - if [ "X$vt" = "X" ]; then - # take a wild guess... - vt=vt16 - warn "$program: selected fallback VT $vt" - fi -else - vt="" -fi - -# Decide flavor of Xserver: -# -stype=`basename "$xserver"` -if echo "$stype" | grep -i xfree86 > /dev/null; then - stype=xfree86 -else - stype=xorg -fi - -tweak_config() { - in="$1" - config2="$XDUMMY_TMPDIR/xdummy_modified_xconfig.conf" - if [ "X$disp" != "X" ]; then - d=`echo "$disp" | sed -e 's,/,,g' -e 's/:/_/g'` - config2="$config2$d" - fi - - # perl script to tweak the config file... add/delete options, etc. - # - env XDUMMY_GEOM=$geom \ - XDUMMY_DEPTH=$depth \ - XDUMMY_NOMODELINES=$nomodelines \ - perl > $config2 < $in -e ' - $n = 0; - $geom = $ENV{XDUMMY_GEOM}; - $depth = $ENV{XDUMMY_DEPTH}; - $nomodelines = $ENV{XDUMMY_NOMODELINES}; - $mode_str = ""; - $videoram = "240000"; - $HorizSync = "30.0 - 130.0"; - $VertRefresh = "50.0 - 250.0"; - if ($geom ne "") { - my $tmp = ""; - foreach $g (split(/,/, $geom)) { - $tmp .= "\"$g\" "; - if (!$nomodelines && $g =~ /(\d+)x(\d+)/) { - my $w = $1; - my $h = $2; - $mode_str .= " Modeline \"$g\" "; - my $dot = sprintf("%.2f", $w * $h * 70 * 1.e-6); - $mode_str .= $dot; - $mode_str .= " " . $w; - $mode_str .= " " . int(1.02 * $w); - $mode_str .= " " . int(1.10 * $w); - $mode_str .= " " . int(1.20 * $w); - $mode_str .= " " . $h; - $mode_str .= " " . int($h + 1); - $mode_str .= " " . int($h + 3); - $mode_str .= " " . int($h + 20); - $mode_str .= "\n"; - } - } - $tmp =~ s/\s*$//; - $geom = $tmp; - } - while (<>) { - if ($ENV{XDUMMY_NOTWEAK}) { - print $_; - next; - } - $n++; - if (/^\s*#/) { - # pass comments straight thru - print; - next; - } - if (/^\s*Section\s+(\S+)/i) { - # start of Section - $sect = $1; - $sect =~ s/\W//g; - $sect =~ y/A-Z/a-z/; - $sects{$sect} = 1; - print; - next; - } - if (/^\s*EndSection/i) { - # end of Section - if ($sect eq "serverflags") { - if (!$got_DontVTSwitch) { - print " ##Xdummy:##\n"; - print " Option \"DontVTSwitch\" \"true\"\n"; - } - if (!$got_AllowMouseOpenFail) { - print " ##Xdummy:##\n"; - print " Option \"AllowMouseOpenFail\" \"true\"\n"; - } - if (!$got_PciForceNone) { - print " ##Xdummy:##\n"; - print " Option \"PciForceNone\" \"true\"\n"; - } - } elsif ($sect eq "device") { - if (!$got_Driver) { - print " ##Xdummy:##\n"; - print " Driver \"dummy\"\n"; - } - if (!$got_VideoRam) { - print " ##Xdummy:##\n"; - print " VideoRam $videoram\n"; - } - } elsif ($sect eq "screen") { - if ($depth ne "" && !got_DefaultDepth) { - print " ##Xdummy:##\n"; - print " DefaultDepth $depth\n"; - } - if ($got_Monitor eq "") { - print " ##Xdummy:##\n"; - print " Monitor \"Monitor0\"\n"; - } - } elsif ($sect eq "monitor") { - if (!got_HorizSync) { - print " ##Xdummy:##\n"; - print " HorizSync $HorizSync\n"; - } - if (!got_VertRefresh) { - print " ##Xdummy:##\n"; - print " VertRefresh $VertRefresh\n"; - } - if (!$nomodelines) { - print " ##Xdummy:##\n"; - print $mode_str; - } - } - $sect = ""; - print; - next; - } - - if (/^\s*SubSection\s+(\S+)/i) { - # start of Section - $subsect = $1; - $subsect =~ s/\W//g; - $subsect =~ y/A-Z/a-z/; - $subsects{$subsect} = 1; - if ($sect eq "screen" && $subsect eq "display") { - $got_Modes = 0; - } - print; - next; - } - if (/^\s*EndSubSection/i) { - # end of SubSection - if ($sect eq "screen") { - if ($subsect eq "display") { - if ($depth ne "" && !$set_Depth) { - print " ##Xdummy:##\n"; - print " Depth\t$depth\n"; - } - if ($geom ne "" && ! $got_Modes) { - print " ##Xdummy:##\n"; - print " Modes\t$geom\n"; - } - } - } - $subsect = ""; - print; - next; - } - - $l = $_; - $l =~ s/#.*$//; - if ($sect eq "serverflags") { - if ($l =~ /^\s*Option.*DontVTSwitch/i) { - $_ =~ s/false/true/ig; - $got_DontVTSwitch = 1; - } - if ($l =~ /^\s*Option.*AllowMouseOpenFail/i) { - $_ =~ s/false/true/ig; - $got_AllowMouseOpenFail = 1; - } - if ($l =~ /^\s*Option.*PciForceNone/i) { - $_ =~ s/false/true/ig; - $got_PciForceNone= 1; - } - } - if ($sect eq "module") { - if ($l =~ /^\s*Load.*\b(dri|fbdevhw)\b/i) { - $_ = "##Xdummy## $_"; - } - } - if ($sect eq "monitor") { - if ($l =~ /^\s*HorizSync/i) { - $got_HorizSync = 1; - } - if ($l =~ /^\s*VertRefresh/i) { - $got_VertRefresh = 1; - } - } - if ($sect eq "device") { - if ($l =~ /^(\s*Driver)\b/i) { - $_ = "$1 \"dummy\"\n"; - $got_Driver = 1; - } - if ($l =~ /^\s*VideoRam/i) { - $got_VideoRam= 1; - } - } - if ($sect eq "inputdevice") { - if ($l =~ /^\s*Option.*\bDevice\b/i) { - print " ##Xdummy:##\n"; - $_ = " Option \"Device\" \"/dev/dilbert$n\"\n"; - } - } - if ($sect eq "screen") { - if ($l =~ /^\s*DefaultDepth\s+(\d+)/i) { - if ($depth ne "") { - print " ##Xdummy:##\n"; - $_ = " DefaultDepth\t$depth\n"; - } - $got_DefaultDepth = 1; - } - if ($l =~ /^\s*Monitor\s+(\S+)/i) { - $got_Monitor = $1; - $got_Monitor =~ s/"//g; - } - if ($subsect eq "display") { - if ($geom ne "") { - if ($l =~ /^(\s*Modes)\b/i) { - print " ##Xdummy:##\n"; - $_ = "$1 $geom\n"; - $got_Modes = 1; - } - } - if ($l =~ /^\s*Depth\s+(\d+)/i) { - my $d = $1; - if (!$set_Depth && $depth ne "") { - $set_Depth = 1; - if ($depth != $d) { - print " ##Xdummy:##\n"; - $_ = " Depth\t$depth\n"; - } - } - } - } - } - print; - } - if ($ENV{XDUMMY_NOTWEAK}) { - exit; - } - # create any crucial sections that are missing: - if (! exists($sects{serverflags})) { - print "\n##Xdummy:##\n"; - print "Section \"ServerFlags\"\n"; - print " Option \"DontVTSwitch\" \"true\"\n"; - print " Option \"AllowMouseOpenFail\" \"true\"\n"; - print " Option \"PciForceNone\" \"true\"\n"; - print "EndSection\n"; - } - if (! exists($sects{device})) { - print "\n##Xdummy:##\n"; - print "Section \"Device\"\n"; - print " Identifier \"Videocard0\"\n"; - print " Driver \"dummy\"\n"; - print " VideoRam $videoram\n"; - print "EndSection\n"; - } - if (! exists($sects{monitor})) { - print "\n##Xdummy:##\n"; - print "Section \"Monitor\"\n"; - print " Identifier \"Monitor0\"\n"; - print " HorizSync $HorizSync\n"; - print " VertRefresh $VertRefresh\n"; - print "EndSection\n"; - } - if (! exists($sects{screen})) { - print "\n##Xdummy:##\n"; - print "Section \"Screen\"\n"; - print " Identifier \"Screen0\"\n"; - print " Device \"Videocard0\"\n"; - if ($got_Monitor ne "") { - print " Monitor \"$got_Monitor\"\n"; - } else { - print " Monitor \"Monitor0\"\n"; - } - if ($depth ne "") { - print " DefaultDepth $depth\n"; - } else { - print " DefaultDepth 24\n"; - } - print " SubSection \"Display\"\n"; - print " Viewport 0 0\n"; - print " Depth 24\n"; - if ($got_Modes) { - ; - } elsif ($geom ne "") { - print " Modes $geom\n"; - } else { - print " Modes \"1280x1024\" \"1024x768\" \"800x600\"\n"; - } - print " EndSubSection\n"; - print "EndSection\n"; - } -'; -} - -# Work out config file and tweak it. -# -if [ "X$cmdline_config" = "X" ]; then - : -elif [ "X$cmdline_config" = "Xxdummy-builtin" ]; then - : -elif echo "$cmdline_config" | grep '/' > /dev/null; then - : -else - # ignore basename only case (let server handle it) - cmdline_config="" - notweak=1 -fi - -config=$cmdline_config - -if [ "X$notweak" = "X1" -a "X$root" = "X" -a -f "$cmdline_config" ]; then - # if not root we need to copy (but not tweak) the specified config. - XDUMMY_NOTWEAK=1 - export XDUMMY_NOTWEAK - notweak="" -fi - -if [ ! $notweak ]; then - # tweaked config will be put in $config2: - config2="" - if [ "X$config" = "X" ]; then - # use the default one: - if [ "X$stype" = "Xxorg" ]; then - config=/etc/X11/xorg.conf - else - if [ -f "/etc/X11/XF86Config-4" ]; then - config="/etc/X11/XF86Config-4" - else - config="/etc/X11/XF86Config" - fi - fi - if [ ! -f "$config" ]; then - for c in /etc/X11/xorg.conf /etc/X11/XF86Config-4 /etc/X11/XF86Config - do - if [ -f $c ]; then - config=$c - break - fi - done - fi - fi - - if [ "X$config" = "Xxdummy-builtin" ]; then - config="" - fi - - if [ ! -f "$config" ]; then - config="$XDUMMY_TMPDIR/xorg.conf" - warn "$program: using minimal built-in xorg.conf settings." - cat > $config < /dev/null; then - so=`echo "$so" | sed -e "s,^\.,$pwd,"` - fi - if echo "$so" | grep '/' > /dev/null; then - : - else - so="$pwd/$so" - fi - warn "env LD_PRELOAD=$so $xserver $disp $args $vt" - warn "" - if [ ! $runit ]; then - exit 0 - fi -fi - -if [ $strace ]; then - if [ "X$strace" = "X2" ]; then - ltrace -f env LD_PRELOAD=$SO $xserver $disp $args $vt - else - strace -f env LD_PRELOAD=$SO $xserver $disp $args $vt - fi -else - exec env LD_PRELOAD=$SO $xserver $disp $args $vt -fi - -exit $? - -######################################################################### - -code() { -#code_begin -#include -#define O_ACCMODE 0003 -#define O_RDONLY 00 -#define O_WRONLY 01 -#define O_RDWR 02 -#define O_CREAT 0100 /* not fcntl */ -#define O_EXCL 0200 /* not fcntl */ -#define O_NOCTTY 0400 /* not fcntl */ -#define O_TRUNC 01000 /* not fcntl */ -#define O_APPEND 02000 -#define O_NONBLOCK 04000 -#define O_NDELAY O_NONBLOCK -#define O_SYNC 010000 -#define O_FSYNC O_SYNC -#define O_ASYNC 020000 - -#include -#include -#include - -#include -#include - -#define __USE_GNU -#include - -static char tmpdir[4096]; -static char str1[4096]; -static char str2[4096]; - -static char devs[256][1024]; -static int debug = -1; -static int root = -1; -static int changed_uid = 0; -static int saw_fonts = 0; -static int saw_lib_modules = 0; - -static time_t start = 0; - -void check_debug(void) { - if (debug < 0) { - if (getenv("XDUMMY_DEBUG") != NULL) { - debug = 1; - } else { - debug = 0; - } - /* prevent other processes using the preload: */ - putenv("LD_PRELOAD="); - } -} -void check_root(void) { - if (root < 0) { - /* script tells us if we are root */ - if (getenv("XDUMMY_ROOT") != NULL) { - root = 1; - } else { - root = 0; - } - } -} - -void check_uid(void) { - if (start == 0) { - start = time(NULL); - if (debug) fprintf(stderr, "START: %u\n", (unsigned int) start); - return; - } else if (changed_uid == 0) { - if (saw_fonts || time(NULL) > start + 20) { - if (getenv("XDUMMY_UID")) { - int uid = atoi(getenv("XDUMMY_UID")); - if (debug) fprintf(stderr, "SETREUID: %d saw_fonts=%d\n", uid, saw_fonts); - if (uid >= 0) { - /* this will simply fail in -nonroot mode: */ - setreuid(uid, -1); - } - } - changed_uid = 1; - } - } -} - -#define CHECKIT if (debug < 0) check_debug(); \ - if (root < 0) check_root(); \ - check_uid(); - -static void set_tmpdir(void) { - char *s; - static int didset = 0; - if (didset) { - return; - } - s = getenv("XDUMMY_TMPDIR"); - if (! s) { - s = "/tmp"; - } - tmpdir[0] = '\0'; - strcat(tmpdir, s); - strcat(tmpdir, "/"); - didset = 1; -} - -static char *tmpdir_path(const char *path) { - char *str; - set_tmpdir(); - strcpy(str2, path); - str = str2; - while (*str) { - if (*str == '/') { - *str = '_'; - } - str++; - } - strcpy(str1, tmpdir); - strcat(str1, str2); - return str1; -} - -int open(const char *pathname, int flags, unsigned short mode) { - int fd; - char *store_dev = NULL; - static int (*real_open)(const char *, int , unsigned short) = NULL; - - CHECKIT - if (! real_open) { - real_open = (int (*)(const char *, int , unsigned short)) - dlsym(RTLD_NEXT, "open"); - } - - if (strstr(pathname, "lib/modules/")) { - /* not currently used. */ - saw_lib_modules = 1; - } - - if (!root) { - if (strstr(pathname, "/dev/") == pathname) { - store_dev = strdup(pathname); - } - if (strstr(pathname, "/dev/tty") == pathname && strcmp(pathname, "/dev/tty")) { - pathname = tmpdir_path(pathname); - if (debug) fprintf(stderr, "OPEN: %s -> %s (as FIFO)\n", store_dev, pathname); - /* we make it a FIFO so ioctl on it does not fail */ - unlink(pathname); - mkfifo(pathname, 0666); - } else if (0) { - /* we used to handle more /dev files ... */ - fd = real_open(pathname, O_WRONLY|O_CREAT, 0777); - close(fd); - } - } - - fd = real_open(pathname, flags, mode); - - if (debug) fprintf(stderr, "OPEN: %s %d %d fd=%d\n", pathname, flags, mode, fd); - - if (! root) { - if (store_dev) { - if (fd < 256) { - strcpy(devs[fd], store_dev); - } - free(store_dev); - } - } - - return(fd); -} - -int open64(const char *pathname, int flags, unsigned short mode) { - int fd; - - CHECKIT - if (debug) fprintf(stderr, "OPEN64: %s %d %d\n", pathname, flags, mode); - - fd = open(pathname, flags, mode); - return(fd); -} - -int rename(const char *oldpath, const char *newpath) { - static int (*real_rename)(const char *, const char *) = NULL; - - CHECKIT - if (! real_rename) { - real_rename = (int (*)(const char *, const char *)) - dlsym(RTLD_NEXT, "rename"); - } - - if (debug) fprintf(stderr, "RENAME: %s %s\n", oldpath, newpath); - - if (root) { - return(real_rename(oldpath, newpath)); - } - - if (strstr(oldpath, "/var/log") == oldpath) { - if (debug) fprintf(stderr, "RENAME: returning 0\n"); - return 0; - } - return(real_rename(oldpath, newpath)); -} - -FILE *fopen(const char *pathname, const char *mode) { - static FILE* (*real_fopen)(const char *, const char *) = NULL; - char *str; - - if (! saw_fonts) { - if (strstr(pathname, "/fonts/")) { - if (strstr(pathname, "fonts.dir")) { - saw_fonts = 1; - } else if (strstr(pathname, "fonts.alias")) { - saw_fonts = 1; - } - } - } - - CHECKIT - if (! real_fopen) { - real_fopen = (FILE* (*)(const char *, const char *)) - dlsym(RTLD_NEXT, "fopen"); - } - - if (debug) fprintf(stderr, "FOPEN: %s %s\n", pathname, mode); - - if (strstr(pathname, "xdummy_modified_xconfig.conf")) { - /* make our config appear to be in /etc/X11, etc. */ - char *q = strrchr(pathname, '/'); - if (q != NULL && getenv("XDUMMY_TMPDIR") != NULL) { - strcpy(str1, getenv("XDUMMY_TMPDIR")); - strcat(str1, q); - if (debug) fprintf(stderr, "FOPEN: %s -> %s\n", pathname, str1); - pathname = str1; - } - } - - if (root) { - return(real_fopen(pathname, mode)); - } - - str = (char *) pathname; - if (strstr(pathname, "/var/log") == pathname) { - str = tmpdir_path(pathname); - if (debug) fprintf(stderr, "FOPEN: %s -> %s\n", pathname, str); - } - return(real_fopen(str, mode)); -} - - -#define RETURN0 if (debug) \ - {fprintf(stderr, "IOCTL: covered %d 0x%x\n", fd, req);} return 0; -#define RETURN1 if (debug) \ - {fprintf(stderr, "IOCTL: covered %d 0x%x\n", fd, req);} return -1; - -int ioctl(int fd, int req, void *ptr) { - static int closed_xf86Info_consoleFd = 0; - static int (*real_ioctl)(int, int , void *) = NULL; - - CHECKIT - if (! real_ioctl) { - real_ioctl = (int (*)(int, int , void *)) - dlsym(RTLD_NEXT, "open"); - } - if (debug) fprintf(stderr, "IOCTL: %d 0x%x %p\n", fd, req, ptr); - - /* based on xorg-x11-6.8.1-dualhead.patch */ - if (req == VT_GETMODE) { - /* close(xf86Info.consoleFd) */ - if (0 && ! closed_xf86Info_consoleFd) { - /* I think better not to close it... */ - close(fd); - closed_xf86Info_consoleFd = 1; - } - RETURN0 - } else if (req == VT_SETMODE) { - RETURN0 - } else if (req == VT_GETSTATE) { - RETURN0 - } else if (req == KDSETMODE) { - RETURN0 - } else if (req == KDSETLED) { - RETURN0 - } else if (req == KDGKBMODE) { - RETURN0 - } else if (req == KDSKBMODE) { - RETURN0 - } else if (req == VT_ACTIVATE) { - RETURN0 - } else if (req == VT_WAITACTIVE) { - RETURN0 - } else if (req == VT_RELDISP) { - if (ptr == (void *) 1) { - RETURN1 - } else if (ptr == (void *) VT_ACKACQ) { - RETURN0 - } - } - - return(real_ioctl(fd, req, ptr)); -} - -typedef void (*sighandler_t)(int); -#define SIGUSR1 10 -#define SIG_DFL ((sighandler_t)0) - -sighandler_t signal(int signum, sighandler_t handler) { - static sighandler_t (*real_signal)(int, sighandler_t) = NULL; - - CHECKIT - if (! real_signal) { - real_signal = (sighandler_t (*)(int, sighandler_t)) - dlsym(RTLD_NEXT, "signal"); - } - - if (debug) fprintf(stderr, "SIGNAL: %d %p\n", signum, handler); - - if (signum == SIGUSR1) { - if (debug) fprintf(stderr, "SIGNAL: skip SIGUSR1\n"); - return SIG_DFL; - } - - return(real_signal(signum, handler)); -} - -int close(int fd) { - static int (*real_close)(int) = NULL; - - CHECKIT - if (! real_close) { - real_close = (int (*)(int)) dlsym(RTLD_NEXT, "close"); - } - - if (debug) fprintf(stderr, "CLOSE: %d\n", fd); - if (!root) { - if (fd < 256) { - devs[fd][0] = '\0'; - } - } - return(real_close(fd)); -} - -struct stat { - int foo; -}; - -int stat(const char *path, struct stat *buf) { - static int (*real_stat)(const char *, struct stat *) = NULL; - - CHECKIT - if (! real_stat) { - real_stat = (int (*)(const char *, struct stat *)) - dlsym(RTLD_NEXT, "stat"); - } - - if (debug) fprintf(stderr, "STAT: %s\n", path); - - return(real_stat(path, buf)); -} - -int stat64(const char *path, struct stat *buf) { - static int (*real_stat64)(const char *, struct stat *) = NULL; - - CHECKIT - if (! real_stat64) { - real_stat64 = (int (*)(const char *, struct stat *)) - dlsym(RTLD_NEXT, "stat64"); - } - - if (debug) fprintf(stderr, "STAT64: %s\n", path); - - return(real_stat64(path, buf)); -} - -int chown(const char *path, uid_t owner, gid_t group) { - static int (*real_chown)(const char *, uid_t, gid_t) = NULL; - - CHECKIT - if (! real_chown) { - real_chown = (int (*)(const char *, uid_t, gid_t)) - dlsym(RTLD_NEXT, "chown"); - } - - if (root) { - return(real_chown(path, owner, group)); - } - - if (debug) fprintf(stderr, "CHOWN: %s %d %d\n", path, owner, group); - - if (strstr(path, "/dev") == path) { - if (debug) fprintf(stderr, "CHOWN: return 0\n"); - return 0; - } - - return(real_chown(path, owner, group)); -} - -extern int *__errno_location (void); -#ifndef ENODEV -#define ENODEV 19 -#endif - -int ioperm(unsigned long from, unsigned long num, int turn_on) { - static int (*real_ioperm)(unsigned long, unsigned long, int) = NULL; - - CHECKIT - if (! real_ioperm) { - real_ioperm = (int (*)(unsigned long, unsigned long, int)) - dlsym(RTLD_NEXT, "ioperm"); - } - if (debug) fprintf(stderr, "IOPERM: %d %d %d\n", (int) from, (int) num, turn_on); - if (root) { - return(real_ioperm(from, num, turn_on)); - } - if (from == 0 && num == 1024 && turn_on == 1) { - /* we want xf86EnableIO to fail */ - if (debug) fprintf(stderr, "IOPERM: setting ENODEV.\n"); - *__errno_location() = ENODEV; - return -1; - } - return 0; -} - -int iopl(int level) { - static int (*real_iopl)(int) = NULL; - - CHECKIT - if (! real_iopl) { - real_iopl = (int (*)(int)) dlsym(RTLD_NEXT, "iopl"); - } - if (debug) fprintf(stderr, "IOPL: %d\n", level); - if (root) { - return(real_iopl(level)); - } - return 0; -} - -#ifdef INTERPOSE_GETUID - -/* - * we got things to work w/o pretending to be root. - * so we no longer interpose getuid(), etc. - */ - -uid_t getuid(void) { - static uid_t (*real_getuid)(void) = NULL; - CHECKIT - if (! real_getuid) { - real_getuid = (uid_t (*)(void)) dlsym(RTLD_NEXT, "getuid"); - } - if (root) { - return(real_getuid()); - } - if (debug) fprintf(stderr, "GETUID: 0\n"); - return 0; -} -uid_t geteuid(void) { - static uid_t (*real_geteuid)(void) = NULL; - CHECKIT - if (! real_geteuid) { - real_geteuid = (uid_t (*)(void)) dlsym(RTLD_NEXT, "geteuid"); - } - if (root) { - return(real_geteuid()); - } - if (debug) fprintf(stderr, "GETEUID: 0\n"); - return 0; -} -uid_t geteuid_kludge1(void) { - static uid_t (*real_geteuid)(void) = NULL; - CHECKIT - if (! real_geteuid) { - real_geteuid = (uid_t (*)(void)) dlsym(RTLD_NEXT, "geteuid"); - } - if (debug) fprintf(stderr, "GETEUID: 0 saw_libmodules=%d\n", saw_lib_modules); - if (root && !saw_lib_modules) { - return(real_geteuid()); - } else { - saw_lib_modules = 0; - return 0; - } -} - -uid_t getuid32(void) { - static uid_t (*real_getuid32)(void) = NULL; - CHECKIT - if (! real_getuid32) { - real_getuid32 = (uid_t (*)(void)) dlsym(RTLD_NEXT, "getuid32"); - } - if (root) { - return(real_getuid32()); - } - if (debug) fprintf(stderr, "GETUID32: 0\n"); - return 0; -} -uid_t geteuid32(void) { - static uid_t (*real_geteuid32)(void) = NULL; - CHECKIT - if (! real_geteuid32) { - real_geteuid32 = (uid_t (*)(void)) dlsym(RTLD_NEXT, "geteuid32"); - } - if (root) { - return(real_geteuid32()); - } - if (debug) fprintf(stderr, "GETEUID32: 0\n"); - return 0; -} - -gid_t getgid(void) { - static gid_t (*real_getgid)(void) = NULL; - CHECKIT - if (! real_getgid) { - real_getgid = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getgid"); - } - if (root) { - return(real_getgid()); - } - if (debug) fprintf(stderr, "GETGID: 0\n"); - return 0; -} -gid_t getegid(void) { - static gid_t (*real_getegid)(void) = NULL; - CHECKIT - if (! real_getegid) { - real_getegid = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getegid"); - } - if (root) { - return(real_getegid()); - } - if (debug) fprintf(stderr, "GETEGID: 0\n"); - return 0; -} -gid_t getgid32(void) { - static gid_t (*real_getgid32)(void) = NULL; - CHECKIT - if (! real_getgid32) { - real_getgid32 = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getgid32"); - } - if (root) { - return(real_getgid32()); - } - if (debug) fprintf(stderr, "GETGID32: 0\n"); - return 0; -} -gid_t getegid32(void) { - static gid_t (*real_getegid32)(void) = NULL; - CHECKIT - if (! real_getegid32) { - real_getegid32 = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getegid32"); - } - if (root) { - return(real_getegid32()); - } - if (debug) fprintf(stderr, "GETEGID32: 0\n"); - return 0; -} -#endif - -#if 0 -/* maybe we need to interpose on strcmp someday... here is the template */ -int strcmp(const char *s1, const char *s2) { - static int (*real_strcmp)(const char *, const char *) = NULL; - CHECKIT - if (! real_strcmp) { - real_strcmp = (int (*)(const char *, const char *)) dlsym(RTLD_NEXT, "strcmp"); - } - if (debug) fprintf(stderr, "STRCMP: '%s' '%s'\n", s1, s2); - return(real_strcmp(s1, s2)); -} -#endif - -#code_end -} diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index e374fdfd4..8eb8e4a3a 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -1,4 +1,5 @@ -# on Debian in lua-posix +--# on Debian in lua-posix +local basedir = "../../" local posix = require "posix" function sleep(sec) @@ -9,19 +10,19 @@ function getTests(testset) return (io.popen("ls " .. testset .. "/*.lua"):lines()) end -print 'Running tests against ../../notion/notion' -print 'Starting Xdummy...' +print('Running tests against ' .. basedir .. 'notion/notion') +print 'Starting Xorg dummy...' local xpid = posix.fork() if (xpid == 0) then - local result,errstr,errno = posix.exec("/bin/sh", "./Xdummy", ":7") - print ('Error replacing current process with Xdummy: ' .. errstr); + local result,errstr,errno = posix.exec("/usr/bin/Xorg", "-noreset", "+extension", "GLX", "+extension", "RANDR", "+extension", "RENDER", "-logfile", "./10.log", "-config", "./xorg.conf", ":7") + print('Error replacing current process with Xorg dummy: ' .. errstr); os.exit(1) end sleep(1) -print '(Hopefully) started Xdummy.' +print '(Hopefully) started Xorg dummy.' local testsets = { 'basic_test', 'xinerama', 'xrandr' } local errors = 0 @@ -32,12 +33,12 @@ for i,testset in ipairs(testsets) do os.execute("rm -r " .. testset .. "/.notion/default-session--7") - print ('Starting notion in ./' .. testset .. '...') + print('Starting notion in ./' .. testset .. '...') local notionpid = posix.fork() if (notionpid == 0) then - local result,errstr,errno = posix.exec("../../notion/notion", "-noerrorlog", "-display", ":7") - print ('Error replacing current process with notion: ' .. errstr) + local result,errstr,errno = posix.exec(basedir .. "notion/notion", "-noerrorlog", "-display", ":7") + print('Error replacing current process with notion: ' .. errstr) os.exit(1) end @@ -46,8 +47,8 @@ for i,testset in ipairs(testsets) do print 'Running tests...' for test in getTests(testset) do - print ('Running test ' .. test) - local testoutputpipe = io.popen("cat " .. test .. " | DISPLAY=:7 notionflux") + print('Running test ' .. test) + local testoutputpipe = io.popen("cat " .. test .. " | DISPLAY=:7 " .. basedir .. "mod_notionflux/notionflux/notionflux") local testoutput = testoutputpipe:read("*a") print 'Evaluating result...' if(testoutput ~= "\"ok\"\n") then @@ -70,5 +71,5 @@ posix.kill(xpid) if errors == 0 then print 'OK!' else - print (errors .. " errors.") + print(errors .. " errors.") end diff --git a/test/integration/xorg.conf b/test/integration/xorg.conf new file mode 100644 index 000000000..6548897fe --- /dev/null +++ b/test/integration/xorg.conf @@ -0,0 +1,64 @@ +# Taken from https://xpra.org/xorg.conf, removed test configs +# This xorg configuration file is meant to be used by xpra +# to start a dummy X11 server. +# For details, please see: +# https://xpra.org/Xdummy.html + +Section "ServerFlags" + Option "DontVTSwitch" "true" + Option "AllowMouseOpenFail" "true" + Option "PciForceNone" "true" + Option "AutoEnableDevices" "false" + Option "AutoAddDevices" "false" +EndSection + +Section "InputDevice" + Identifier "dummy_mouse" + Option "CorePointer" "true" + Driver "void" +EndSection + +Section "InputDevice" + Identifier "dummy_keyboard" + Option "CoreKeyboard" "true" + Driver "void" +EndSection + +Section "Device" + Identifier "dummy_videocard" + Driver "dummy" + Option "ConstantDPI" "true" + VideoRam 92000 +EndSection + +Section "Monitor" + Identifier "dummy_monitor" + HorizSync 5.0 - 1000.0 + VertRefresh 5.0 - 200.0 + Modeline "1440x900" 30.66 1440 1472 1584 1616 900 921 924 946 + ModeLine "1366x768" 72.00 1366 1414 1446 1494 768 771 777 803 + Modeline "1360x768" 24.49 1360 1392 1480 1512 768 786 789 807 + Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841 + Modeline "1280x768" 23.11 1280 1312 1392 1424 768 786 789 807 + Modeline "1024x768" 18.71 1024 1056 1120 1152 768 786 789 807 + Modeline "800x600" 14.50 800 832 880 912 600 614 617 631 +EndSection + +Section "Screen" + Identifier "dummy_screen" + Device "dummy_videocard" + Monitor "dummy_monitor" + DefaultDepth 24 + SubSection "Display" + Viewport 0 0 + Depth 24 + Modes "1440x900" "1366x768" "1360x768" "1280x800" "1280x768" "1024x768" "800x600" + EndSubSection +EndSection + +Section "ServerLayout" + Identifier "dummy_layout" + Screen "dummy_screen" + InputDevice "dummy_mouse" + InputDevice "dummy_keyboard" +EndSection From 6860002731149e1c42c4ddd8219739c734628723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Wed, 1 May 2019 22:50:50 -0300 Subject: [PATCH 05/18] Check if posix module exists, otherwise, skip integration --- test/Makefile | 1 - test/integration/runtests.lua | 28 +++++++++++++++------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/test/Makefile b/test/Makefile index d10004540..cead640f1 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,4 @@ .PHONY: test test: - # For now integration tests don't work (lua-posix problems), skipping them $(MAKE) -C integration test diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index 8eb8e4a3a..fef6f12c4 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -1,6 +1,13 @@ --# on Debian in lua-posix local basedir = "../../" -local posix = require "posix" + +print("[TESTING] Integration") + +local success, posix = pcall(require, "posix") +if not success then + print("[SKIP] posix module not found") + os.exit(0) +end function sleep(sec) os.execute("sleep " .. tonumber(sec)) @@ -22,16 +29,13 @@ end sleep(1) -print '(Hopefully) started Xorg dummy.' - local testsets = { 'basic_test', 'xinerama', 'xrandr' } local errors = 0 for i,testset in ipairs(testsets) do - posix.setenv('HOME', testset); - os.execute("rm -r " .. testset .. "/.notion/default-session--7") + os.execute("rm -rf " .. testset .. "/.notion/default-session--7") print('Starting notion in ./' .. testset .. '...') @@ -44,18 +48,15 @@ for i,testset in ipairs(testsets) do sleep(2) - print 'Running tests...' - for test in getTests(testset) do - print('Running test ' .. test) + print('[TEST] ' .. test) local testoutputpipe = io.popen("cat " .. test .. " | DISPLAY=:7 " .. basedir .. "mod_notionflux/notionflux/notionflux") local testoutput = testoutputpipe:read("*a") - print 'Evaluating result...' if(testoutput ~= "\"ok\"\n") then - print('** ERROR ** ' .. testoutput) + print('[ERROR] ' .. testoutput) errors = errors + 1 else - print '** OK **' + print '[OK]' end end @@ -69,7 +70,8 @@ print 'Killing X process...' posix.kill(xpid) if errors == 0 then - print 'OK!' + print '[OK]' else - print(errors .. " errors.") + print('[ERROR] ' .. errors .. " tests failed.") end +os.exit(errors) From 21f54aa04daf0c1981aa3cedfe0bc147c7542e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Wed, 22 May 2019 06:56:56 -0300 Subject: [PATCH 06/18] Find Xorg binary in PATH --- test/integration/runtests.lua | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index fef6f12c4..4713bc2dd 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -17,13 +17,34 @@ function getTests(testset) return (io.popen("ls " .. testset .. "/*.lua"):lines()) end +local function file_exists(name) + local f=io.open(name,"r") + if f~=nil then io.close(f) return true else return false end +end + +local function find_in_path(file) + local env_path = os.getenv("PATH") + local paths = string.gmatch(env_path, "[^:]+") + for path in paths do + local fullfilename = path .. '/' .. file + if file_exists(fullfilename) then + return fullfilename + end + end + return false +end + print('Running tests against ' .. basedir .. 'notion/notion') -print 'Starting Xorg dummy...' local xpid = posix.fork() if (xpid == 0) then - local result,errstr,errno = posix.exec("/usr/bin/Xorg", "-noreset", "+extension", "GLX", "+extension", "RANDR", "+extension", "RENDER", "-logfile", "./10.log", "-config", "./xorg.conf", ":7") - print('Error replacing current process with Xorg dummy: ' .. errstr); + local xorg_binary = find_in_path("Xorg") + if xorg_binary == false then + print('Error launching Xorg dummy, Xorg binary not found') + end + print('Starting Xorg dummy: ' .. xorg_binary) + local result,errstr,errno = posix.exec(xorg_binary, "-noreset", "+extension", "GLX", "+extension", "RANDR", "+extension", "RENDER", "-logfile", "./10.log", "-config", "./xorg.conf", ":7") + print('Error replacing current process with Xorg dummy: ' .. errstr) os.exit(1) end From 06013d813a480c53712d435291586b0dcce2aaeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Thu, 2 May 2019 22:38:33 -0300 Subject: [PATCH 07/18] wip integration readme --- test/integration/README | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/integration/README b/test/integration/README index b096ac12a..c1c5f3c37 100644 --- a/test/integration/README +++ b/test/integration/README @@ -2,17 +2,19 @@ Each subdirectory here is an integration test. == Requirements == -- xserver-xorg-video-dummy -- lposix (aka lua-posix in Debian) +- xserver-xorg-video-dummy +- luaposix (aka lua-posix in Debian) + - Debian base distros: ```apt-get install lua-posix``` + - All distros using luarocks: ```luarocks install luaposix``` == Running the tests == -Install notion and run 'make test' +Run ```make test``` on notion's source directory == How it works == Each integration test basically looks like this: -- Start a dummy X server (Xdummy) +- Start a dummy X server (X's dummy dirver) - Start notion with the configuration in $test/config - basically $test/config behaves like the ~user/.notion dir for this test - Right now this starts the currenly *installed* notion. @@ -28,6 +30,5 @@ Each integration test basically looks like this: - the x.org dummy driver does not appear to support RandR - .. but we might be able to test some of the mod_xinerama stuff with fakexinerama -- there might be some SELINUX noise, probably due to the way Xdummy works - Xdummy doesn't properly autodetect which X ports are free, so we use a fixed value of :7 From 89a65ca87c5d23171bc69606491233981f73f7ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Wed, 15 Jan 2020 06:57:23 -0300 Subject: [PATCH 08/18] Fix test success message "ok" as it now also outputs print stuff Due to the improvements on notionflux where print() strings are also sent to output, we now check if the test's output buffer ends with "ok" instead of expecting it to be the only output. --- test/integration/runtests.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index 4713bc2dd..01a1ed466 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -73,7 +73,8 @@ for i,testset in ipairs(testsets) do print('[TEST] ' .. test) local testoutputpipe = io.popen("cat " .. test .. " | DISPLAY=:7 " .. basedir .. "mod_notionflux/notionflux/notionflux") local testoutput = testoutputpipe:read("*a") - if(testoutput ~= "\"ok\"\n") then + local okend = "\"ok\"\n" + if(testoutput == "" or testoutput:sub(-#okend) ~= okend) then print('[ERROR] ' .. testoutput) errors = errors + 1 else From e96b9522b0a8abf5fec8cd7cd254af4641fc995f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Wed, 15 Jan 2020 20:20:09 -0300 Subject: [PATCH 09/18] make test now fails when lua-posix is not found --- test/integration/runtests.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index 01a1ed466..8678ff052 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -5,8 +5,8 @@ print("[TESTING] Integration") local success, posix = pcall(require, "posix") if not success then - print("[SKIP] posix module not found") - os.exit(0) + print("[ERROR] posix module not found") + os.exit(1) end function sleep(sec) From 50de2c2bf5c91b8fd9fd8dd9feb34de55f019b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Wed, 15 Jan 2020 20:29:03 -0300 Subject: [PATCH 10/18] travis: install lua-posix and correct the symlink --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 01462cc1d..e9cca168d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,9 @@ compiler: env: - - USE_XFT=0 -before_install: sudo apt-get install lua5.2 liblua5.2-dev gettext libxft-dev libxinerama-dev libxrandr-dev libreadline-dev +before_install: + - sudo apt-get install lua5.2 liblua5.2-dev gettext libxft-dev libxinerama-dev libxrandr-dev libreadline-dev lua-posix + - sudo ln -sf /usr/lib/x86_64-linux-gnu/lua/5.2/posix_c.so /usr/lib/x86_64-linux-gnu/lua/5.2/posix.so script: - make - make test From 13cc5ad87a7ea1ac9443005a019d1985dba99e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Thu, 30 Jan 2020 08:15:35 -0300 Subject: [PATCH 11/18] If running inside Travis, assume we have Xfvb running, change DISPLAY to :99 Based on https://www.electronjs.org/docs/tutorial/testing-on-headless-ci#travis-ci --- .travis.yml | 7 +++++++ test/integration/runtests.lua | 24 ++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index e9cca168d..c477b426a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,13 @@ language: c compiler: - gcc - clang +addons: + apt: + packages: + - xvfb +install: + - export DISPLAY=':99.0' + - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & env: - - USE_XFT=0 diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index 8678ff052..f8c9b4885 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -1,8 +1,16 @@ --# on Debian in lua-posix -local basedir = "../../" print("[TESTING] Integration") +local running_on_travis = os.getenv('TRAVIS') +local notion_binary = "../../notion/notion" +local notionflux_binary = "../../mod_notionflux/notionflux/notionflux" +if running_on_travis then + print('TRAVIS detected') + -- notion_binary = "/usr/local/bin/notion" + -- notionflux_binary = "/usr/local/bin/notionflux" +end + local success, posix = pcall(require, "posix") if not success then print("[ERROR] posix module not found") @@ -34,16 +42,20 @@ local function find_in_path(file) return false end -print('Running tests against ' .. basedir .. 'notion/notion') +print('Running tests against ' .. notion_binary) local xpid = posix.fork() if (xpid == 0) then + if running_on_travis then + print('TRAVIS should have Xfvb running') + os.exit(1) + end local xorg_binary = find_in_path("Xorg") if xorg_binary == false then print('Error launching Xorg dummy, Xorg binary not found') end print('Starting Xorg dummy: ' .. xorg_binary) - local result,errstr,errno = posix.exec(xorg_binary, "-noreset", "+extension", "GLX", "+extension", "RANDR", "+extension", "RENDER", "-logfile", "./10.log", "-config", "./xorg.conf", ":7") + local result,errstr,errno = posix.exec(xorg_binary, "-noreset", "+extension", "GLX", "+extension", "RANDR", "+extension", "RENDER", "-logfile", "./99.log", "-config", "./xorg.conf", ":99") print('Error replacing current process with Xorg dummy: ' .. errstr) os.exit(1) end @@ -56,13 +68,13 @@ local errors = 0 for i,testset in ipairs(testsets) do posix.setenv('HOME', testset); - os.execute("rm -rf " .. testset .. "/.notion/default-session--7") + os.execute("rm -rf " .. testset .. "/.notion/default-session--99") print('Starting notion in ./' .. testset .. '...') local notionpid = posix.fork() if (notionpid == 0) then - local result,errstr,errno = posix.exec(basedir .. "notion/notion", "-noerrorlog", "-display", ":7") + local result,errstr,errno = posix.exec(notion_binary, "-noerrorlog", "-display", ":99") print('Error replacing current process with notion: ' .. errstr) os.exit(1) end @@ -71,7 +83,7 @@ for i,testset in ipairs(testsets) do for test in getTests(testset) do print('[TEST] ' .. test) - local testoutputpipe = io.popen("cat " .. test .. " | DISPLAY=:7 " .. basedir .. "mod_notionflux/notionflux/notionflux") + local testoutputpipe = io.popen("cat " .. test .. " | DISPLAY=:99 " .. notionflux_binary) local testoutput = testoutputpipe:read("*a") local okend = "\"ok\"\n" if(testoutput == "" or testoutput:sub(-#okend) ~= okend) then From 63e3d5ce6ed4fc85729675549ec80a0e153e3916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Thu, 30 Jan 2020 09:25:01 -0300 Subject: [PATCH 12/18] Add dev searchdirs as we do not issue make install on travis --- test/integration/runtests.lua | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index f8c9b4885..6bbe81a0d 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -2,13 +2,13 @@ print("[TESTING] Integration") +local basedir = "../../" +local notion_binary = basedir .. "notion/notion" +local notionflux_binary = basedir .. "mod_notionflux/notionflux/notionflux" + local running_on_travis = os.getenv('TRAVIS') -local notion_binary = "../../notion/notion" -local notionflux_binary = "../../mod_notionflux/notionflux/notionflux" if running_on_travis then print('TRAVIS detected') - -- notion_binary = "/usr/local/bin/notion" - -- notionflux_binary = "/usr/local/bin/notionflux" end local success, posix = pcall(require, "posix") @@ -74,7 +74,28 @@ for i,testset in ipairs(testsets) do local notionpid = posix.fork() if (notionpid == 0) then - local result,errstr,errno = posix.exec(notion_binary, "-noerrorlog", "-display", ":99") + local result,errstr,errno = posix.exec( + notion_binary, + "-noerrorlog", + "-s", basedir .. "contrib/scripts", + "-s", basedir .. "de", + "-s", basedir .. "etc", + "-s", basedir .. "ioncore", + "-s", basedir .. "mod_dock", + "-s", basedir .. "mod_menu", + "-s", basedir .. "mod_mgmtmode", + "-s", basedir .. "mod_notionflux", + "-s", basedir .. "mod_query", + "-s", basedir .. "mod_sm", + "-s", basedir .. "mod_sp", + "-s", basedir .. "mod_statusbar", + "-s", basedir .. "mod_statusbar/ion-statusd", + "-s", basedir .. "mod_tiling", + "-s", basedir .. "mod_xinerama", + "-s", basedir .. "mod_xkbevents", + "-s", basedir .. "mod_xrandr", + "-display", ":99" + ) print('Error replacing current process with notion: ' .. errstr) os.exit(1) end From 11abdb1a4e1b27b07e8ffe2db037c8ee1422fb76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Thu, 30 Jan 2020 10:13:25 -0300 Subject: [PATCH 13/18] Copy & paste mod_xrandr_mock inside xrandr tests I don't know why it's not finding mod_xrandr_mock now, I'd appreciate some help. --- test/integration/xrandr/01_remove_display.lua | 45 +++++++++++++++++++ .../integration/xrandr/02_removed_display.lua | 45 +++++++++++++++++++ .../xrandr/03_new_screen_has_ws.lua | 45 +++++++++++++++++++ 3 files changed, 135 insertions(+) diff --git a/test/integration/xrandr/01_remove_display.lua b/test/integration/xrandr/01_remove_display.lua index f9f34556a..8330f5358 100644 --- a/test/integration/xrandr/01_remove_display.lua +++ b/test/integration/xrandr/01_remove_display.lua @@ -1,3 +1,48 @@ +-- TEMP +-- See why it's not finding mod_xrandr_mock +-- overwrite some methods in mod_xrandr to mock it +print('Mocking RandR inplementation') + +local outputOne = { name = 'ONE', x = 0, y = 0, w = 1280, h = 960 } +local outputTwo = { name = 'TWO', x = 1280, y = 0, w = 1280, h = 1024 } + +local n_screens = 2 + +function mod_xrandr.get_outputs(reg) + if reg:geom().x == 0 then + return { ONE = outputOne } + elseif n_screens > 1 then + return { TWO = outputTwo } + else + return {} + end +end + +function mod_xrandr.get_all_outputs() + if n_screens > 1 then + return { ONE = outputOne, TWO = outputTwo } + else + return { ONE = outputOne } + end +end + +function mx_names(mx) + local result = '' + mx:mx_i(function(child) result = result .. child:name() .. ', ' return true end) + return result +end + +mod_xrandr_mock = {} +function mod_xrandr_mock.set_number_of_screens(n) + n_screens = n + if n == 1 then + os.execute("cp xrandr/fakexinerama-1monitor xrandr/.fakexinerama") + else + os.execute("cp xrandr/fakexinerama-2monitors xrandr/.fakexinerama") + end +end +-- /TEMP + if not notioncore.find_screen_id(0) then return "Initial number of screens should be 2, first screen not found" elseif not notioncore.find_screen_id(1) then diff --git a/test/integration/xrandr/02_removed_display.lua b/test/integration/xrandr/02_removed_display.lua index 1dda7497d..b928ad5cf 100644 --- a/test/integration/xrandr/02_removed_display.lua +++ b/test/integration/xrandr/02_removed_display.lua @@ -1,3 +1,48 @@ +-- TEMP +-- See why it's not finding mod_xrandr_mock +-- overwrite some methods in mod_xrandr to mock it +print('Mocking RandR inplementation') + +local outputOne = { name = 'ONE', x = 0, y = 0, w = 1280, h = 960 } +local outputTwo = { name = 'TWO', x = 1280, y = 0, w = 1280, h = 1024 } + +local n_screens = 2 + +function mod_xrandr.get_outputs(reg) + if reg:geom().x == 0 then + return { ONE = outputOne } + elseif n_screens > 1 then + return { TWO = outputTwo } + else + return {} + end +end + +function mod_xrandr.get_all_outputs() + if n_screens > 1 then + return { ONE = outputOne, TWO = outputTwo } + else + return { ONE = outputOne } + end +end + +function mx_names(mx) + local result = '' + mx:mx_i(function(child) result = result .. child:name() .. ', ' return true end) + return result +end + +mod_xrandr_mock = {} +function mod_xrandr_mock.set_number_of_screens(n) + n_screens = n + if n == 1 then + os.execute("cp xrandr/fakexinerama-1monitor xrandr/.fakexinerama") + else + os.execute("cp xrandr/fakexinerama-2monitors xrandr/.fakexinerama") + end +end +-- /TEMP + mod_xrandr.screenlayoutupdated() if notioncore.find_screen_id(1) then diff --git a/test/integration/xrandr/03_new_screen_has_ws.lua b/test/integration/xrandr/03_new_screen_has_ws.lua index 6f208d8a8..f165856d1 100644 --- a/test/integration/xrandr/03_new_screen_has_ws.lua +++ b/test/integration/xrandr/03_new_screen_has_ws.lua @@ -1,3 +1,48 @@ +-- TEMP +-- See why it's not finding mod_xrandr_mock +-- overwrite some methods in mod_xrandr to mock it +print('Mocking RandR inplementation') + +local outputOne = { name = 'ONE', x = 0, y = 0, w = 1280, h = 960 } +local outputTwo = { name = 'TWO', x = 1280, y = 0, w = 1280, h = 1024 } + +local n_screens = 2 + +function mod_xrandr.get_outputs(reg) + if reg:geom().x == 0 then + return { ONE = outputOne } + elseif n_screens > 1 then + return { TWO = outputTwo } + else + return {} + end +end + +function mod_xrandr.get_all_outputs() + if n_screens > 1 then + return { ONE = outputOne, TWO = outputTwo } + else + return { ONE = outputOne } + end +end + +function mx_names(mx) + local result = '' + mx:mx_i(function(child) result = result .. child:name() .. ', ' return true end) + return result +end + +mod_xrandr_mock = {} +function mod_xrandr_mock.set_number_of_screens(n) + n_screens = n + if n == 1 then + os.execute("cp xrandr/fakexinerama-1monitor xrandr/.fakexinerama") + else + os.execute("cp xrandr/fakexinerama-2monitors xrandr/.fakexinerama") + end +end +-- /TEMP + mod_xrandr.screenlayoutupdated() if (notioncore.find_screen_id(1) == Nil) then From b8a80d6e6168aa542c5c751abb6d1d8f60863b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Thu, 30 Jan 2020 10:29:57 -0300 Subject: [PATCH 14/18] "Fixed" xrandr integration tests Probably either notion/notionflux behaviour changed while the tests weren't run or something broke on the tests. I'd like some feedback here. --- test/integration/xrandr/01_remove_display.lua | 4 ++-- test/integration/xrandr/02_removed_display.lua | 8 ++++---- test/integration/xrandr/03_new_screen_has_ws.lua | 9 ++++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/test/integration/xrandr/01_remove_display.lua b/test/integration/xrandr/01_remove_display.lua index 8330f5358..9211b6fc6 100644 --- a/test/integration/xrandr/01_remove_display.lua +++ b/test/integration/xrandr/01_remove_display.lua @@ -67,8 +67,8 @@ print('Updating layout when there is 2 screens present') -- remove one, and then leave checking that one was removed up to the next test. mod_xrandr.screenlayoutupdated() -if notioncore.find_screen_id(0):mx_count() ~= 1 then - return "After updating screen 0 should have 1 workspaces instead of " .. +if notioncore.find_screen_id(0):mx_count() ~= 2 then + return "After updating screen 0 should have 2 workspaces instead of " .. notioncore.find_screen_id(0):mx_count() .. ": " .. mx_names(notioncore.find_screen_id(0)) end if notioncore.find_screen_id(1):mx_count() ~= 1 then diff --git a/test/integration/xrandr/02_removed_display.lua b/test/integration/xrandr/02_removed_display.lua index b928ad5cf..32af966a5 100644 --- a/test/integration/xrandr/02_removed_display.lua +++ b/test/integration/xrandr/02_removed_display.lua @@ -45,12 +45,12 @@ end mod_xrandr.screenlayoutupdated() -if notioncore.find_screen_id(1) then - return "New number of screens should be 1, found ", notioncore.find_screen_id(1):name() +if notioncore.find_screen_id(1) ~= nil then + return "New number of screens should be 1, found " .. notioncore.find_screen_id(1):name() end -if notioncore.find_screen_id(0):mx_count() ~= 2 then - return "Remaining screen should have 2 workspaces instead of " .. notioncore.find_screen_id(0):mx_count() .. +if notioncore.find_screen_id(0):mx_count() ~= 3 then + return "Remaining screen should have 3 workspaces instead of " .. notioncore.find_screen_id(0):mx_count() .. ': ' .. mx_names(notioncore.find_screen_id(0)) end diff --git a/test/integration/xrandr/03_new_screen_has_ws.lua b/test/integration/xrandr/03_new_screen_has_ws.lua index f165856d1..8ea5dd232 100644 --- a/test/integration/xrandr/03_new_screen_has_ws.lua +++ b/test/integration/xrandr/03_new_screen_has_ws.lua @@ -45,7 +45,7 @@ end mod_xrandr.screenlayoutupdated() -if (notioncore.find_screen_id(1) == Nil) then +if (notioncore.find_screen_id(1) == nil) then return "Number of screens should be 2, again at the start of this test" end @@ -58,8 +58,11 @@ end if notioncore.find_screen_id(0):mx_nth(0):name() ~= 'WGroupWS' then return "First workspace not correctly returned to first screen" end -if notioncore.find_screen_id(1):mx_nth(0):name() ~= 'WGroupWS<1>' then - return "Second workspace not correctly returned to second screen" +if notioncore.find_screen_id(0):mx_nth(1):name() ~= 'WGroupWS<1>' then + return "Second workspace correctly kept on first screen" +end +if notioncore.find_screen_id(1):mx_nth(0):name() ~= 'WGroupWS<2>' then + return "Second screen did not get new workspace: " .. notioncore.find_screen_id(1):mx_nth(0):name() end return "ok" From 2339935bad536d12006ef54a20d3ae1de39c81b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Thu, 30 Jan 2020 12:10:25 -0300 Subject: [PATCH 15/18] get some sleep before running the tests --- test/integration/runtests.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index 6bbe81a0d..4c8425722 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -60,7 +60,7 @@ if (xpid == 0) then os.exit(1) end -sleep(1) +sleep(3) local testsets = { 'basic_test', 'xinerama', 'xrandr' } local errors = 0 @@ -100,7 +100,7 @@ for i,testset in ipairs(testsets) do os.exit(1) end - sleep(2) + sleep(3) for test in getTests(testset) do print('[TEST] ' .. test) @@ -117,7 +117,7 @@ for i,testset in ipairs(testsets) do print 'Killing notion process...' posix.kill(notionpid) - sleep(1) + sleep(3) end From 9acff1548513911ddb40fec7cade6cf4c74356b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Thu, 30 Jan 2020 12:31:27 -0300 Subject: [PATCH 16/18] send SIGKILL to notion process --- test/integration/runtests.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/integration/runtests.lua b/test/integration/runtests.lua index 4c8425722..510b58566 100644 --- a/test/integration/runtests.lua +++ b/test/integration/runtests.lua @@ -115,8 +115,9 @@ for i,testset in ipairs(testsets) do end end - print 'Killing notion process...' - posix.kill(notionpid) + print('Killing notion process...') + posix.kill(notionpid, posix.SIGKILL) + print(posix.wait(notionpid)) sleep(3) end From 2a0d44ee9a77d419cb5a01337e9ae727b8741163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Fri, 31 Jan 2020 01:24:19 -0300 Subject: [PATCH 17/18] Fix xrandr 03 test error message --- test/integration/xrandr/03_new_screen_has_ws.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/xrandr/03_new_screen_has_ws.lua b/test/integration/xrandr/03_new_screen_has_ws.lua index 8ea5dd232..a59a11ec2 100644 --- a/test/integration/xrandr/03_new_screen_has_ws.lua +++ b/test/integration/xrandr/03_new_screen_has_ws.lua @@ -59,7 +59,7 @@ if notioncore.find_screen_id(0):mx_nth(0):name() ~= 'WGroupWS' then return "First workspace not correctly returned to first screen" end if notioncore.find_screen_id(0):mx_nth(1):name() ~= 'WGroupWS<1>' then - return "Second workspace correctly kept on first screen" + return "Second workspace not correctly returned on first screen" end if notioncore.find_screen_id(1):mx_nth(0):name() ~= 'WGroupWS<2>' then return "Second screen did not get new workspace: " .. notioncore.find_screen_id(1):mx_nth(0):name() From cf506c6a41a5d23152bdf35ae93d6b81b20888e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Bonveh=C3=AD?= Date: Wed, 4 Mar 2020 12:06:34 -0300 Subject: [PATCH 18/18] Improve xinerama 02_removed_display error check and message --- test/integration/xinerama/02_removed_display.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/xinerama/02_removed_display.lua b/test/integration/xinerama/02_removed_display.lua index 90c2337bc..3a76d762c 100644 --- a/test/integration/xinerama/02_removed_display.lua +++ b/test/integration/xinerama/02_removed_display.lua @@ -1,7 +1,7 @@ mod_xinerama.refresh(); -if notioncore.find_screen_id(1) then - return "New number of screens should be 1, found ", notioncore.find_screen_id(1):name() +if notioncore.find_screen_id(1) ~= nil then + return "New number of screens should be 1, found " .. notioncore.find_screen_id(1):name() end os.execute("cp xinerama/fakexinerama-2monitors xinerama/.fakexinerama");