Commit 88394ddb authored by Jérome Perrin's avatar Jérome Perrin

Selenium Server

New software release, selenium server, which expose a http server to which clients can connect using [`webdriver.Remote`](https://selenium-python.readthedocs.io/getting-started.html#using-selenium-with-remote-webdriver) and then use standard webdriver API to control the browser.

The server is made of :
 * the "hub" to which webdriver connects
 * a Xvfb server
 * some nodes, for different browsers:
   * Firefox 52
   * Firefox 60
   * Chrome 69
 * an IPv6 https frontend, exposing the admin interface and the hub. Note that python's webdriver binding before 3.14.0 refuse to connect to a hub with a non verified SSL certificate, so for now clients must either use the published `backend-url` (which is IPv4) or use a version of selenium eggs >= 3.14. In the future we'll see how [caucase](https://lab.nexedi.com/nexedi/caucase/) can solve this. Also, this behavior might also change with future version of selenium, because it's wrong that it does not verify SSL certificates.
 * a ssh server, to which you can connect to establish a ssh tunnel with port forward and register more nodes to the hub. This can be used to connect a browser running on your desktop and see the test running, run unsupported browsers, maybe also [appium](http://appium.io/docs/en/advanced-concepts/grid/) to run tests on mobile. This is a kind of "extra feature" that seems working, but I'm not sure we can support it.

To achieve this, we had to :
  * update Xorg components and build gtk with a X11 gdk backend  to be able to run firefox 60. Updating xorg/gdk also fixed a bug in firefox 52, before this, firefox 52 was not able to get the screen size and ` window.screen.width` was 0. Now firefox 52 can get the screen size properly but resizing window does not work.
  * update chrome 69 and fix a few missing `$LD_LIBRARY_PATH` in the wrapper.

Everything seems working, including taking screenshots, uploading files and resizing window - except resizing window does not work on firefox 52.

See the included test suite for some example usage. Basically it's same as what we're doing today, but instead of:

```python
driver = webdriver.Firefox(path_to_firefox)
```

we use:

```python
driver = webdriver.Remote(
   command_executor='http://127.0.0.1:4444/wd/hub', # the url or backend-url parameter published by the instance.
   desired_capabilities={
      'browserName': 'firefox', # or chrome
      'version': '60', # or don't set a version if you want any version (browserName, on the other hand, is required)
   })
```


/reviewed-on nexedi/slapos!420
parents bc662696 ffafffdb
# ChromeDriver - Webdriver for Chrome
# http://chromedriver.chromium.org/
# This is a binary download with wrapper scripts.
[buildout]
extends =
../chromium/buildout.cfg
../nss/buildout.cfg
../nspr/buildout.cfg
parts =
chromedriver-wrapper
[chromedriver-wrapper-2.41]
<= chromedriver-wrapper
wrapper-name = chromedriver-2.41
part = ${chromedriver-2.41:location}
[chromedriver-wrapper]
# generate a wrapper named ${:wrapper-name} setting $LD_LIBRARY_PATH
# to run chromedriver installed from ${:part}
wrapper-name = chromedriver
part = ${chromedriver:location}
recipe = slapos.recipe.build
location = ${buildout:bin-directory}/${:wrapper-name}
script =
chromedriver = self.options['part']
part = self.buildout[os.path.basename(chromedriver)]
with open(%(location)r, 'w') as f:
f.write("""#!/bin/sh -e
cd {}
export LD_LIBRARY_PATH=$PWD:{}
export PATH={}:$PATH
exec ./chromedriver "$@"
""".format(
chromedriver,
':'.join(part['library'].split()),
':'.join(part['path'].split()),
))
os.fchmod(f.fileno(), 0o755)
[chromedriver]
<= chromedriver-2.41
[chromedriver-2.41]
<= chromedriver-download
version = 2.41
# Supports Chrome v67-69
md5sum-x86_64 = fbd8b9561575054e0e7e9cc53b680a70
[chromedriver-download]
# Installs chromedriver ${version}.
# This chromedriver is not usable directly, it needs a wrapper.
version =
md5sum-x86_64 =
recipe = slapos.recipe.build
x86-64 = https://chromedriver.storage.googleapis.com/${:version}/chromedriver_linux64.zip ${:md5sum-x86_64}
library =
${nss:location}/lib
${nspr:location}/lib
path =
script =
url, md5sum = self.options[guessPlatform()].split()
extract_dir = self.extract(self.download(url, md5sum))
os.mkdir(%(location)r)
shutil.copy(extract_dir + '/chromedriver', %(location)r)
# Chromium binary build, from "Downloading old builds of Chrome / Chromium" of
# https://www.chromium.org/getting-involved/download-chromium
# Currently, only Linux_x64 is supported.
[buildout]
# chromium binary is linking to libudev, that can be provided by
# component/systemd. but current component/systemd can be built only
# with Linux kernel >= 3.7. so libudev is not included in
# LD_LIBRARY_PATH below intentionally and libudev should be installed
# in the system.
extends =
../alsa/buildout.cfg
../coreutils/buildout.cfg
../cups/buildout.cfg
../dbus/buildout.cfg
......@@ -14,6 +19,7 @@ extends =
../gettext/buildout.cfg
../glib/buildout.cfg
../gtk-2/buildout.cfg
../gtk-3/buildout.cfg
../libexpat/buildout.cfg
../libffi/buildout.cfg
../libpng/buildout.cfg
......@@ -27,77 +33,133 @@ extends =
../zlib/buildout.cfg
parts =
chromium
chromium-wrapper
[chromium-wrapper]
# Install a chromium wrapper named ${:wrapper-name} in buildout's bin-directory,
# wrapping chromium installed in ${:part}
# This [chromium-wrapper] installs the default chromium with name `chromium` and
# can also be used as a macro to install under a different name.
wrapper-name = chromium
part = ${chromium:location}
recipe = slapos.recipe.build
location = ${buildout:bin-directory}/${:wrapper-name}
script =
chromeium = self.options['part']
part = self.buildout[os.path.basename(chromeium)]
with open(%(location)r, 'w') as f:
f.write("""#!/bin/sh -e
cd {}
# this also needs a $FONTCONFIG_FILE set, otherwise system fonts will be used and if
# no system fonts are available, chrome will refuse to start with this error:
# FATAL:platform_font_linux.cc(83)] Check failed: InitDefaultFont(). Could not find the default font
export LD_LIBRARY_PATH=$PWD:{}
export PATH={}:$PATH
exec ./chrome --disable-setuid-sandbox --no-sandbox --disable-gpu $@
""".format(
chromeium,
':'.join(part['library'].split()),
':'.join(part['path'].split()),
))
os.fchmod(f.fileno(), 0o755)
[chromium-wrapper-69]
<= chromium-wrapper
wrapper-name = chromium-69
part = ${chromium-69:location}
[chromium]
<= chromium-69
[chromium-69]
<= chromium-download
version = 69.0.3497.0
revision_x86-64 = 576753
md5sum-x86_64 = 08ac27fd40ace4ca8dfbd1db403deccb
generation-x86_64 = 1532051976706023
[chromium-download]
# macro to download a binary build of chromium and generate a
# wrapper as chrome-slapos in the part directory
# the full version tag
version =
# needs the following URL parts:
# revision is from the "base position"
revision_x86-64 =
# generation is in the final download URL
generation-x86_64 =
# this is the md5sum of the downloaded archive
md5sum-x86_64 =
recipe = slapos.recipe.build
slapos_promise =
file:chrome
file:chrome-wrapper
file:chrome-slapos
# How to get the revision :
# stable : https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Linux_x64%2FLAST_CHANGE?alt=media
# snapshot : https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2FLAST_CHANGE?alt=media
revision_x86 = 382014
revision_x86-64 = 382014
revision_mac = 381909
linux_x86 = https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Linux%2F${:revision_x86}%2Fchrome-linux.zip?alt=media
linux_x86-64 = https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Linux_x64%2F${:revision_x86-64}%2Fchrome-linux.zip?alt=media ef2c476b1f059e9aa026bbac1872368d
mac_x86-64 = https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Mac%2F${:revision_mac}%2Fchrome-linux.zip?alt=media
x86-64 = https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2F${:revision_x86-64}%2Fchrome-linux.zip?generation=${:generation-x86_64}&alt=media ${:md5sum-x86_64}
library =
${atk:location}/lib
${at-spi2-atk:location}/lib
${alsa:location}/lib
${cairo:location}/lib
${cups:location}/lib
${cups:location}/lib64
${dbus:location}/lib/
${dbus-glib:location}/lib/
${fontconfig:location}/lib/
${gdk-pixbuf:location}/lib
${gettext:location}/lib
${glib:location}/lib
${gtk-3:location}/lib
${harfbuzz:location}/lib
${libX11:location}/lib
${libXau:location}/lib
${libXcomposite:location}/lib
${libXcursor:location}/lib
${libXext:location}/lib
${libXi:location}/lib
${libXrender:location}/lib/
${libXtst:location}/lib
${libXScrnSaver:location}/lib
${libXrandr:location}/lib
${libexpat:location}/lib
${libffi:location}/lib
${libpng:location}/lib
${libpng12:location}/lib
${libxcb:location}/lib
${libxml2:location}/lib
${mesa:location}/lib
${nspr:location}/lib
${nss:location}/lib
${pango:location}/lib
${pcre:location}/lib
${pixman:location}/lib
${sqlite3:location}/lib
${xdamage:location}/lib
${xfixes:location}/lib
${zlib:location}/lib
path =
${fontconfig:location}/bin
script =
#If part directory already exist, will just throw an error.
url, md5sum = self.options[guessPlatform()].split()
extract_dir = self.extract(self.download(url, md5sum))
self.copyTree(guessworkdir(extract_dir), %(location)r)
# XXX adjust some permissions
import os
platform = '%%s_%%s' %% (guessOperatingSystem(), guessPlatform())
if not self.options.get('url'): self.options['url'], self.options['md5sum'] = self.options[platform].split(' ')
extract_dir = self.extract(self.download(self.options['url'], self.options.get('md5sum')))
workdir = guessworkdir(extract_dir)
self.copyTree(workdir, "%(location)s")
wrapper_location = os.path.join("%(location)s", "chrome-slapos")
wrapper = open(wrapper_location, 'w')
wrapper.write("""#!/bin/sh
export LD_LIBRARY_PATH="%(location)s"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${atk:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${cairo:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${cups:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${dbus:location}/lib/"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${dbus-glib:location}/lib/"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${fontconfig:location}/lib/"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${gdk-pixbuf:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${gettext:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${glib:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${gtk-2:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${harfbuzz:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libX11:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libXau:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libXcomposite:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libXcursor:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libXext:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libXi:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libXrender:location}/lib/"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libXtst:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libexpat:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libffi:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libpng:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libpng12:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libxcb:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libxml2:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${mesa:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${nspr:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${nss:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pango:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pcre:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pixman:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${sqlite3:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${xdamage:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${xfixes:location}/lib"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${zlib:location}/lib"
exec %(location)s/chrome --disable-setuid-sandbox --disable-gpu $*""")
wrapper.flush()
wrapper.close()
os.system('"${findutils:location}/bin/find" "%(location)s" -type d -exec "${coreutils:location}/bin/chmod" a+rx {} \;')
os.system('"${findutils:location}/bin/find" "%(location)s" -type f -executable -exec "${coreutils:location}/bin/chmod" a+rx {} \;')
os.system('"${findutils:location}/bin/find" "%(location)s" -type f -exec "${coreutils:location}/bin/chmod" a+r {} \;')
os.chmod(wrapper_location, 0755)
......@@ -31,7 +31,6 @@ part = ${firefox:location}
recipe = slapos.recipe.build
location = ${buildout:bin-directory}/${:wrapper-name}
part = ${firefox:location}
script =
firefox = self.options['part']
part = self.buildout[os.path.basename(firefox)]
......@@ -48,6 +47,11 @@ script =
))
os.fchmod(f.fileno(), 0o755)
[firefox-wrapper-60]
<= firefox-wrapper
wrapper-name = firefox-60
part = ${firefox-60:location}
[firefox-wrapper-52]
<= firefox-wrapper
wrapper-name = firefox-52
......@@ -67,6 +71,12 @@ part = ${firefox-51:location}
# would not be created.
<= firefox-52
[firefox-60]
<= firefox-download
version = 60.0.2esr
i686-md5sum = ce7c80716036dfb5c2fb1ca2538556ff
x86_64-md5sum = 6fe25d9a3fcc82670320242c9047d1da
[firefox-52]
<= firefox-download
version = 52.9.0esr
......@@ -143,7 +153,25 @@ script =
[geckodriver]
# Current geckodriver installed as buildout:bin-directory/geckodriver
<= geckodriver-0.17.0
<= geckodriver-0.21.0
[geckodriver-0.22.0]
<= geckodriver-base
version = 0.22.0
i686-md5sum = 6de7544753fda56fbaa8382dcac99aaa
x86_64-md5sum = 81746200ce5841e00cabf3b8ea7db542
[geckodriver-0.21.0]
<= geckodriver-base
version = 0.21.0
i686-md5sum = 9fc1657dd1b94272d0cdb3b29ca80f79
x86_64-md5sum = 6bc36d4fd4975e296cdb3fa3c5e26a41
[geckodriver-0.19.0]
<= geckodriver-base
version = 0.19.0
i686-md5sum = 07cd383c8aef8ea5ef194a506141afd6
x86_64-md5sum = ca6935a72fd0527d15a78a17a35e56e8
[geckodriver-0.17.0]
<= geckodriver-base
......@@ -151,6 +179,11 @@ version = 0.17.0
i686-md5sum = 79b1a158f96d29942a111c0905f1c807
x86_64-md5sum = be18faeea6e7db9db6990d8667e2298f
[geckodriver-0.16.1]
<= geckodriver-base
version = 0.16.1
i686-md5sum = not not on github
x86_64-md5sum = 57dfd55d4759d9878eb75b4c0123d00c
[geckodriver-0.14.0]
<= geckodriver-base
......
[buildout]
extends =
../xz-utils/buildout.cfg
../p7zip/buildout.cfg
parts =
liberation-fonts
......
......@@ -16,6 +16,7 @@ extends =
../perl/buildout.cfg
../pkgconfig/buildout.cfg
../xorg/buildout.cfg
../icu/buildout.cfg
../xz-utils/buildout.cfg
../zlib/buildout.cfg
......@@ -49,13 +50,13 @@ recipe = slapos.recipe.cmmi
shared = true
url = http://www.freedesktop.org/software/harfbuzz/release/harfbuzz-0.9.35.tar.bz2
md5sum = 531ee8650626ecddcd90b2a4637e31d4
pkg_config_depends = ${cairo:location}/lib/pkgconfig:${cairo:pkg_config_depends}
pkg_config_depends = ${cairo:location}/lib/pkgconfig:${cairo:pkg_config_depends}:${icu4c:location}/lib/pkgconfig
configure-options =
--disable-static
--disable-gtk-doc-html
--with-cairo
--with-freetype
--without-icu
--with-icu
environment =
PATH=${glib:location}/bin:${freetype:location}/bin:${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${:pkg_config_depends}
......@@ -126,5 +127,5 @@ environment =
PATH=${gdk-pixbuf:location}/bin:${gettext:location}/bin:${glib:location}/bin:${perl:location}/bin:${pkgconfig:location}/bin:${xz-utils:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${:pkg_config_depends}
# not taken from pkg-config result...
CPPFLAGS=-I${libX11:location}/include/ -I${xproto:location}/include -I${kbproto:location}/include -I${libXrender:location}/include -I${render:location}/include -I${libXext:location}/include
CPPFLAGS=-I${libX11:location}/include/ -I${xproto:location}/include -I${kbproto:location}/include -I${libXrender:location}/include -I${renderext:location}/include -I${libXext:location}/include
LDFLAGS=-L${libX11:location}/lib -L${libXext:location}/lib -L${libXrender:location}/lib -L${gettext:location}/lib -Wl,-rpath=${gettext:location}/lib -L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib
......@@ -35,19 +35,24 @@ environment =
recipe = slapos.recipe.cmmi
url = http://ftp.gnome.org/pub/gnome/core/3.22/3.22.2/sources/gtk+-3.22.3.tar.xz
md5sum = f0e6492896a2ca244501142319adaa95
pkg_config_depends = ${at-spi2-atk:location}/lib/pkgconfig:${at-spi2-core:location}/lib/pkgconfig:${dbus:location}/lib/pkgconfig:${glib:location}/lib/pkgconfig:${libepoxy:location}/lib/pkgconfig:${pango:location}/lib/pkgconfig:${pango:pkg_config_depends}:${atk:location}/lib/pkgconfig:${gdk-pixbuf:location}/lib/pkgconfig:${libXi:location}/lib/pkgconfig:${pcre:location}/lib/pkgconfig
pkg_config_depends = ${at-spi2-atk:location}/lib/pkgconfig:${at-spi2-core:location}/lib/pkgconfig:${dbus:location}/lib/pkgconfig:${glib:location}/lib/pkgconfig:${libepoxy:location}/lib/pkgconfig:${pango:location}/lib/pkgconfig:${pango:pkg_config_depends}:${atk:location}/lib/pkgconfig:${gdk-pixbuf:location}/lib/pkgconfig:${libXi:pkg_config_depends}:${libXi:location}/lib/pkgconfig:${pcre:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libX11:pkg_config_depends}:${libX11:location}/lib/pkgconfig:${xorgproto:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${libXrender:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${xcbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libXinerama:location}/lib/pkgconfig:${libXrandr:pkg_config_depends}:${libXrandr:location}/lib/pkgconfig:${xfixes:location}/lib/pkgconfig:${libXcomposite:location}/lib/pkgconfig:${xdamage:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${fixesproto:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig:${kbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${compositeproto:location}/lib/pkgconfig:${fixesproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${xfixes:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig:${xproto:location}/lib/pkgconfig:${damageproto:location}/lib/pkgconfig:${xfixes:location}/lib/pkgconfig:${fixesproto:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig
configure-options =
--disable-static
--disable-glibtest
--disable-cups
--disable-papi
--enable-explicit-deps
--disable-xinerama
--disable-gtk-doc-html
--disable-man
--enable-x11-backend
--enable-xrandr
--enable-xfixes
--enable-xcomposite
--enable-xdamage
environment =
PATH=${gdk-pixbuf:location}/bin:${gettext:location}/bin:${glib:location}/bin:${perl:location}/bin:${pkgconfig:location}/bin:${xz-utils:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${:pkg_config_depends}
# not taken from pkg-config result...
CPPFLAGS=-I${cairo:location}/include -I${inputproto:location}/include -I${libX11:location}/include -I${libXi:location}/include -I${xproto:location}/include -I${kbproto:location}/include -I${libXrender:location}/include -I${render:location}/include -I${libXext:location}/include
LDFLAGS=-L${libX11:location}/lib -L${libXi:location}/lib -L${libXext:location}/lib -L${libXrender:location}/lib -L${gettext:location}/lib -Wl,-rpath=${gettext:location}/lib -L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib
CPPFLAGS=-I${cairo:location}/include -I${inputproto:location}/include -I${libX11:location}/include -I${libXi:location}/include -I${xproto:location}/include -I${kbproto:location}/include -I${libXrender:location}/include -I${renderext:location}/include -I${libXext:location}/include -I${libX11:location}/include -I${libXinerama:location}/include -I${gdk-pixbuf:location}/include -I${libXrandr:location}/include -I${xfixes:location}/include -I${libXcomposite:location}/include -I${xdamage:location}/include -I${fixesproto:location}/include
LDFLAGS=-L${libX11:location}/lib -L${libXi:location}/lib -L${libXext:location}/lib -L${libXrender:location}/lib -L${gettext:location}/lib -Wl,-rpath=${gettext:location}/lib -L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${libX11:location}/lib -Wl,-rpath=${libX11:location}/lib -L${libXinerama:location}/lib -Wl,-rpath=${libXinerama:location}/lib -L${gdk-pixbuf:location}/lib -Wl,-rpath=${gdk-pixbuf:location}/lib -L${libXrandr:location}/lib -Wl,-rpath=${libXrandr:location}/lib -L${xfixes:location}/lib -Wl,-rpath=${xfixes:location}/lib -L${libXcomposite:location}/lib -Wl,-rpath=${libXcomposite:location}/lib -L${xdamage:location}/lib -Wl,-rpath=${xdamage:location}/lib
......@@ -26,7 +26,7 @@ configure-options =
environment =
PATH=${freetype:location}/bin:${gcc:location}/bin:${perl:location}/bin:${pkgconfig:location}/bin:${xz-utils:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${:pkg_config_depends}
CPPFLAGS=-I${libX11:location}/include -I${libXrender:location}/include -I${render:location}/include -I${xproto:location}/include
CPPFLAGS=-I${libX11:location}/include -I${libXrender:location}/include -I${renderext:location}/include -I${xproto:location}/include
LD_LIBRARY_PATH=${gcc:location}/lib:${gcc:location}/lib64
LDFLAGS=-Wl,-rpath=${gcc:location}/lib -Wl,-rpath=${gcc:location}/lib64 -L${libX11:location}/lib -Wl,-rpath=${libX11:location}/lib -L${libXext:location}/lib -Wl,-rpath=${libXext:location}/lib -L${libXrender:location}/lib -Wl,-rpath=${libXrender:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib
......
[buildout]
extends =
../libffi/buildout.cfg
../pkgconfig/buildout.cfg
parts =
python-pynacl
[python-pynacl]
recipe = zc.recipe.egg:custom
egg = pynacl
environment = python-pynacl-env
library-dirs =
${libffi:location}/lib/
rpath =
${libffi:location}/lib/
[python-pynacl-env]
PATH = ${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH = ${libffi:location}/lib/pkgconfig
......@@ -19,6 +19,7 @@ configure-options =
--disable-static
--disable-gl
--disable-wic
--enable-everything
--with-jpegincludedir=${libjpeg:location}/include
--with-jpeglibdir=${libjpeg:location}/lib
--with-tiffincludedir=${libtiff:location}/include
......
......@@ -33,14 +33,14 @@ ACLOCAL=${xorg-util-macros:location}/share/aclocal
[xorg-util-macros]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/util-macros-1.17.tar.bz2
md5sum = 4f41667e1bf4938bb2b24fa09d517f77
url = https://www.x.org/releases/individual/util/util-macros-1.19.2.tar.gz
md5sum = 5059b328fac086b733ffac6607164c41
[xproto]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/xproto-7.0.23.tar.bz2
md5sum = d4d241a4849167e4e694fe73371c328c
url = https://www.x.org/releases/individual/proto/xproto-7.0.31.tar.gz
md5sum = 04b925bf9e472c80f9212615cd684f1e
configure-options =
--disable-specs
--without-xmlto
......@@ -52,8 +52,8 @@ environment =
[xextproto]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/xextproto-7.2.1.tar.bz2
md5sum = eaac343af094e6b608cf15cfba0f77c5
url = https://www.x.org/releases/individual/proto/xextproto-7.3.0.tar.gz
md5sum = 37b700baa8c8ea7964702d948dd13821
configure-options =
--disable-specs
--without-xmlto
......@@ -65,8 +65,8 @@ environment =
[xtrans]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/xtrans-1.2.7.tar.bz2
md5sum = 84c66908cf003ad8c272b0eecbdbaee3
url = https://www.x.org/releases/individual/lib/xtrans-1.3.5.tar.gz
md5sum = 6e4eac1b7c6591da0753052e1eccfb58
patches =
${:_profile_base_location_}/xtrans_tmp_env.patch#${xtrans_tmp_env.patch:md5sum}
patch-options = -p1
......@@ -81,8 +81,8 @@ environment =
[libXau]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXau-1.0.7.tar.bz2
md5sum = 2d241521df40d27034413436d1a1465c
url = https://www.x.org/releases/individual/lib/libXau-1.0.8.tar.gz
md5sum = a85cd601d82bc79c0daa280917572e20
configure-options =
--disable-static
environment =
......@@ -92,8 +92,8 @@ environment =
[xcbproto]
recipe = slapos.recipe.cmmi
shared = true
url = http://xcb.freedesktop.org/dist/xcb-proto-1.8.tar.bz2
md5sum = a5de3432cc6e43cc6a27f241dbb991b1
url = https://xcb.freedesktop.org/dist/xcb-proto-1.13.tar.bz2
md5sum = abe9aa4886138150bbc04ae4f29b90e3
environment =
PATH=${libxml2:location}/bin:%(PATH)s
PYTHON=${buildout:executable}
......@@ -101,14 +101,15 @@ environment =
[xorg-libpthread-stubs]
recipe = slapos.recipe.cmmi
shared = true
url = http://xcb.freedesktop.org/dist/libpthread-stubs-0.3.tar.bz2
md5sum = e8fa31b42e13f87e8f5a7a2b731db7ee
url = https://www.x.org/releases/individual/xcb/libpthread-stubs-0.4.tar.gz
md5sum = 7d2734e604a3e2f6f665c420b835ab62
[libxcb]
recipe = slapos.recipe.cmmi
shared = true
url = http://xcb.freedesktop.org/dist/libxcb-1.9.1.tar.bz2
md5sum = ed632cb0dc31b6fbd7ea5c0f931cf5a4
url = https://xorg.freedesktop.org/archive/individual/xcb/libxcb-1.13.tar.bz2
md5sum = c2b6cf928afa16b0047c974e7aaa783f
patches =
${:_profile_base_location_}/libxcb_tmp_env.patch#${libxcb_tmp_env.patch:md5sum}
patch-options = -p1
......@@ -146,8 +147,8 @@ configure-options =
[inputproto]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/inputproto-2.2.tar.bz2
md5sum = 13c8aedaf98a92e282b7e456c0a5bed9
url = https://www.x.org/releases/individual/proto/inputproto-2.3.2.tar.gz
md5sum = 6450bad6f8d5ebe354b01b734d1fd7ca
environment =
PKG_CONFIG_PATH=${xorg-util-macros:location}/share/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -155,8 +156,8 @@ environment =
[kbproto]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/kbproto-1.0.6.tar.bz2
md5sum = 677ea8523eec6caca86121ad2dca0b71
url = https://www.x.org/releases/individual/proto/kbproto-1.0.7.tar.gz
md5sum = 19acc5f02ae80381e216f443134e0bbb
environment =
PKG_CONFIG_PATH=${xorg-util-macros:location}/share/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -164,8 +165,8 @@ environment =
[libX11]
recipe = slapos.recipe.cmmi
shared = true
url = http://ftp.x.org/pub/individual/lib/libX11-1.6.2.tar.bz2
md5sum = c35d6ad95b06635a524579e88622fdb5
url = https://www.x.org/releases/individual/lib/libX11-1.6.6.tar.gz
md5sum = 3fd4c6b9f2333dbc5d16824baa1cfb67
pkg_config_depends = ${inputproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig:${xproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig
configure-options =
--disable-static
......@@ -186,8 +187,8 @@ environment =
[libXdmcp]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXdmcp-1.1.1.tar.bz2
md5sum = b94af6cef211cf3ee256f7e81f70fcd9
url = https://www.x.org/releases/individual/lib/libXdmcp-1.1.2.tar.gz
md5sum = ab0d6a38f0344a05d698ec7d48cfa5a8
environment =
PKG_CONFIG_PATH=${xorg-util-macros:location}/share/pkgconfig:${xproto:location}/lib/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -232,15 +233,25 @@ environment =
PKG_CONFIG_PATH=${xorg-util-macros:location}/share/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
[randrproto]
[presentproto]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/randrproto-1.3.2.tar.bz2
md5sum = 597491c0d8055e2a66f11350c4985775
url = https://www.x.org/releases/individual/proto/presentproto-1.1.tar.gz
md5sum = dc689e8569eda66b8c404e355f575119
environment =
PKG_CONFIG_PATH=${xorg-util-macros:location}/share/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
[xorgproto]
recipe = slapos.recipe.cmmi
shared = true
url = https://www.x.org/releases/individual/proto/xorgproto-2018.4.tar.gz
md5sum = 2763268f5bc742e337415bfedf06b845
pkg_config_depends = ${xorg-util-macros:location}/share/pkgconfig
environment =
PKG_CONFIG_PATH=${:pkg_config_depends}
PATH=${pkgconfig:location}/bin:%(PATH)s
[renderproto]
recipe = slapos.recipe.cmmi
shared = true
......@@ -253,8 +264,8 @@ environment =
[videoproto]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/videoproto-2.3.1.tar.bz2
md5sum = c3b348c6e2031b72b11ae63fc7f805c2
url = https://www.x.org/releases/individual/proto/videoproto-2.3.3.tar.gz
md5sum = d984100603ee2420072f27bb491f4b7d
environment =
PKG_CONFIG_PATH=${xorg-util-macros:location}/share/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -262,8 +273,8 @@ environment =
[fontsproto]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/fontsproto-2.1.2.tar.bz2
md5sum = c5f4f1fb4ba7766eedbc9489e81f3be2
url = https://www.x.org/releases/individual/proto/fontsproto-2.1.3.tar.gz
md5sum = 0415f0360e33f3202af67c6c46782251
configure-options =
--disable-specs
--without-xmlto
......@@ -310,8 +321,8 @@ configure-options =
[libfontenc]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libfontenc-1.1.1.tar.bz2
md5sum = a2a861f142c3b4367f14fc14239fc1f7
url = https://www.x.org/releases/individual/lib/libfontenc-1.1.3.tar.gz
md5sum = 0ffa28542aa7d246299b1f7211cdb768
environment =
PKG_CONFIG_PATH=${xorg-util-macros:location}/share/pkgconfig:${xproto:location}/lib/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -321,8 +332,19 @@ environment =
[libXfont]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXfont-1.4.5.tar.bz2
md5sum = 6851da5dae0a6cf5f7c9b9e2b05dd3b4
url = https://www.x.org/releases/individual/lib/libXfont-1.5.4.tar.gz
md5sum = 562cc729034de3442d860f1c50508c8b
environment =
PKG_CONFIG_PATH=${fontsproto:location}/lib/pkgconfig:${freetype:pkg_config_depends}:${freetype:location}/lib/pkgconfig:${libfontenc:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig:${xproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
CPPFLAGS=-I${zlib:location}/include
LDFLAGS=-L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib
[libXfont2]
recipe = slapos.recipe.cmmi
shared = true
url = https://www.x.org/releases/individual/lib/libXfont2-2.0.3.tar.gz
md5sum = ba7277762e3737cd8dcb6c7fe5113a34
environment =
PKG_CONFIG_PATH=${fontsproto:location}/lib/pkgconfig:${freetype:pkg_config_depends}:${freetype:location}/lib/pkgconfig:${libfontenc:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig:${xproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -332,8 +354,8 @@ environment =
[libxkbfile]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libxkbfile-1.0.8.tar.bz2
md5sum = 19e6533ae64abba0773816a23f2b9507
url = https://www.x.org/releases/individual/lib/libxkbfile-1.0.9.tar.gz
md5sum = 5aab87eba67f37dd910a19be5c1129ee
environment =
PKG_CONFIG_PATH=${kbproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig:${xproto:location}/lib/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -343,8 +365,8 @@ environment =
[xkeyboard-config]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/xkeyboard-config-2.6.tar.bz2
md5sum = e7e31da9adb56ba52b5c18226b8cbef3
url = https://www.x.org/releases/individual/data/xkeyboard-config-2.5.1.tar.gz
md5sum = 62c6583b4ec5775717e7c8b05732763c
configure-options =
--disable-static
--enable-shared
......@@ -357,8 +379,8 @@ environment =
[xkbcomp]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/xkbcomp-1.2.4.tar.bz2
md5sum = a0fc1ac3fc4fe479ade09674347c5aa0
url = https://www.x.org/releases/individual/app/xkbcomp-1.4.2.tar.gz
md5sum = 84b6bafb660181a8c2572981a7fff54d
# Hardcoded location for xkeyboard-config, needed during compile time
xkeyboard-config-location = ${libxkbfile:location}/../xkeyboard-config/share/X11/xkb
configure-options =
......@@ -368,7 +390,7 @@ environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
LDFLAGS=-L${libX11:location}/lib -Wl,-rpath=${libX11:location}/lib -L${libxkbfile:location}/lib -Wl,-rpath=${libxkbfile:location}/lib
[render]
[renderext]
recipe = slapos.recipe.cmmi
shared = true
url = http://xlibs.freedesktop.org/release/renderext-0.9.tar.bz2
......@@ -377,19 +399,19 @@ md5sum = d43c2afc69937655d13c02588c9ff974
[libXrender]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXrender-0.9.7.tar.bz2
md5sum = ee62f4c7f0f16ced4da63308963ccad2
url = https://www.x.org/releases/individual/lib/libXrender-0.9.10.tar.gz
md5sum = 98a14fc11aee08b4a1769426ab4b23a3
configure-options =
--disable-static
environment =
PKG_CONFIG_PATH=${kbproto:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${render:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig
PKG_CONFIG_PATH=${kbproto:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${renderext:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
[libXinerama]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXinerama-1.1.2.tar.bz2
md5sum = cb45d6672c93a608f003b6404f1dd462
url = https://www.x.org/releases/individual/lib/libXinerama-1.1.4.tar.gz
md5sum = 416f5afc64b8d064187b3508081dd194
environment =
PKG_CONFIG_PATH=${kbproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${xineramaproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -399,8 +421,8 @@ configure-options =
[libICE]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libICE-1.0.8.tar.bz2
md5sum = 471b5ca9f5562ac0d6eac7a0bf650738
url = https://www.x.org/releases/individual/lib/libICE-1.0.9.tar.gz
md5sum = 95812d61df8139c7cacc1325a26d5e37
configure-options =
--disable-static
--without-xmlto
......@@ -412,8 +434,8 @@ environment =
[libSM]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libSM-1.2.1.tar.bz2
md5sum = 766de9d1e1ecf8bf74cebe2111d8e2bd
url = https://www.x.org/releases/individual/lib/libSM-1.2.2.tar.gz
md5sum = 18e5084ed9500b1b47719fd1758f0ec8
configure-options =
--disable-static
--without-xmlto
......@@ -426,8 +448,8 @@ environment =
[libXt]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXt-1.1.3.tar.bz2
md5sum = a6f137ae100e74ebe3b71eb4a38c40b3
url = https://www.x.org/releases/individual/lib/libXt-1.1.5.tar.gz
md5sum = 77d317fbc508dd6adefb59d57a663032
configure-options =
--disable-static
environment =
......@@ -437,8 +459,8 @@ environment =
[dri2proto]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/dri2proto-2.6.tar.bz2
md5sum = 2eb74959684f47c862081099059a11ab
url = https://www.x.org/releases/individual/proto/dri2proto-2.8.tar.gz
md5sum = 19ea18f63d8ae8053c9fa84b60365b77
configure-options =
--disable-static
environment =
......@@ -449,8 +471,8 @@ environment =
[pciaccess]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libpciaccess-0.13.1.tar.bz2
md5sum = 399a419ac6a54f0fc07c69c9bdf452dc
url = https://www.x.org/releases/individual/lib/libpciaccess-0.14.tar.gz
md5sum = 344872335233111f44504d3f7cb71bb3
configure-options =
--disable-static
environment =
......@@ -459,8 +481,8 @@ environment =
[makedepend]
recipe = slapos.recipe.cmmi
shared = true
url = http://xorg.freedesktop.org/releases/individual/util/makedepend-1.0.3.tar.bz2
md5sum = 4e6cb97bbecfbb34f3f644a75e513093
url = https://www.x.org/releases/individual/util/makedepend-1.0.5.tar.gz
md5sum = efb2d7c7e22840947863efaedc175747
configure-options =
--disable-static
environment =
......@@ -470,8 +492,8 @@ environment =
[glproto]
recipe = slapos.recipe.cmmi
shared = true
url = http://xorg.freedesktop.org/releases/individual/proto/glproto-1.4.14.tar.bz2
md5sum = f48257daf0017f7a7667e5bf48ca3578
url = https://www.x.org/releases/individual/proto/glproto-1.4.17.tar.gz
md5sum = d69554c1b51a83f2c6976a640819911b
configure-options =
--disable-static
environment =
......@@ -481,8 +503,8 @@ environment =
[xfixes]
recipe = slapos.recipe.cmmi
shared = true
url = http://xorg.freedesktop.org/releases/individual/lib/libXfixes-4.0.5.tar.bz2
md5sum = 1b4b8386bd5d1751b2c7177223ad4629
url = https://www.x.org/releases/individual/lib/libXfixes-5.0.3.tar.gz
md5sum = fd07d0d77e92b0a72ca1740a72322837
configure-options =
--disable-static
environment =
......@@ -492,8 +514,8 @@ environment =
[xdamage]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXdamage-1.1.3.tar.bz2
md5sum = 44774e1a065158b52f1a0da5100cebec
url = https://www.x.org/releases/individual/lib/libXdamage-1.1.4.tar.gz
md5sum = 95867778da012623815214769007c0d7
configure-options =
--disable-static
environment =
......@@ -503,8 +525,8 @@ environment =
[libxmu]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXmu-1.1.1.tar.bz2
md5sum = a4efff8de85bd45dd3da124285d10c00
url = https://www.x.org/releases/individual/lib/libXmu-1.1.2.tar.gz
md5sum = d5be323b02e6851607205c8e941b4e61
environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${xextproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${libXt:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libICE:location}/lib/pkgconfig:${libSM:location}/lib/pkgconfig
......@@ -518,8 +540,8 @@ md5sum = 98482f65ba1e74a08bf5b056a4031ef0
[libXcomposite]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXcomposite-0.4.3.tar.bz2
md5sum = a60e0b5c276d0aa9e2d3b982c98f61c8
url = https://www.x.org/releases/individual/lib/libXcomposite-0.4.4.tar.gz
md5sum = af860b1554a423735d831e6f29ac1ef5
configure-options =
--disable-static
environment =
......@@ -529,19 +551,19 @@ environment =
[libXcursor]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXcursor-1.1.13.tar.bz2
md5sum = 52efa81b7f26c8eda13510a2fba98eea
url = https://www.x.org/releases/individual/lib/libXcursor-1.1.15.tar.gz
md5sum = 837cd0d40afa6ecdafaf6f7b574a0899
configure-options =
--disable-static
environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${render:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${fixesproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${xfixes:location}/lib/pkgconfig:${libXrender:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig
PKG_CONFIG_PATH=${renderext:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${fixesproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${xfixes:location}/lib/pkgconfig:${libXrender:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig
[xwd]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/xwd-1.0.5.tar.bz2
md5sum = 2113126f9ac9c02bb8547c112c5d037e
url = https://www.x.org/releases/individual/app/xwd-1.0.7.tar.gz
md5sum = 3ebd74f7a1980305e5e19ec8ff7aa794
environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${xorg-util-macros:location}/share/pkgconfig:${xproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libxkbfile:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig
......@@ -552,14 +574,13 @@ environment =
# Adds Xvfb functionnality
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/xorg-server-1.12.2.tar.bz2
md5sum = 791f0323b886abb7954de7f042bb7dc6
url = https://www.x.org/releases/individual/xserver/xorg-server-1.20.1.tar.gz
md5sum = f5ba68452b1710306aabc32308c6ac59
patches =
${:_profile_base_location_}/xorg-server_tmp_env.patch#${xorg-server_tmp_env.patch:md5sum}
patch-options = -p1
configure-options =
--enable-xvfb
--disable-aiglx
--disable-composite
--disable-screensaver
--disable-glx
......@@ -572,7 +593,7 @@ configure-options =
--with-xkb-path=${xkeyboard-config:location}/share/X11/xkb
--with-sha1=libgcrypt
environment =
PKG_CONFIG_PATH=${pixman:location}/lib/pkgconfig:${openssl:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig:${fixesproto:location}/lib/pkgconfig:${damageproto:location}/lib/pkgconfig:${xcmiscproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig:${bigreqsproto:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${randrproto:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${inputproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${fontsproto:location}/lib/pkgconfig:${videoproto:location}/lib/pkgconfig:${recordproto:location}/lib/pkgconfig:${resourceproto:location}/lib/pkgconfig:${xineramaproto:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libxkbfile:location}/lib/pkgconfig:${libXfont:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libfontenc:location}/lib/pkgconfig:${freetype:pkg_config_depends}:${freetype:location}/lib/pkgconfig:${zlib:location}/lib/pkgconfig
PKG_CONFIG_PATH=${pixman:location}/lib/pkgconfig:${openssl:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig:${fixesproto:location}/lib/pkgconfig:${damageproto:location}/lib/pkgconfig:${xcmiscproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig:${bigreqsproto:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${xorgproto:pkg_config_depends}:${xorgproto:location}/share/pkgconfig:${renderproto:location}/lib/pkgconfig:${presentproto:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${inputproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${fontsproto:location}/lib/pkgconfig:${videoproto:location}/lib/pkgconfig:${recordproto:location}/lib/pkgconfig:${resourceproto:location}/lib/pkgconfig:${xineramaproto:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libxkbfile:location}/lib/pkgconfig:${libXfont:location}/lib/pkgconfig:${libXfont2:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libfontenc:location}/lib/pkgconfig:${freetype:pkg_config_depends}:${freetype:location}/lib/pkgconfig:${zlib:location}/lib/pkgconfig
CPPFLAGS=-I${bzip2:location}/include -I${libgcrypt:location}/include -I${libgpg-error:location}/include -I${zlib:location}/include
PATH=${patch:location}/bin:${pkgconfig:location}/bin:%(PATH)s
LDFLAGS=-L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -L${libgcrypt:location}/lib -Wl,-rpath=${libgcrypt:location}/lib -L${libgpg-error:location}/lib -Wl,-rpath=${libgpg-error:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib
......@@ -580,9 +601,9 @@ environment =
[libXi]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXi-1.6.1.tar.bz2
md5sum = 78ee882e1ff3b192cf54070bdb19938e
pkg_config_depends = ${inputproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig
url = https://www.x.org/releases/individual/lib/libXi-1.7.9.tar.gz
md5sum = 7f0483d3fa110092b75378b3c926566f
pkg_config_depends = ${inputproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${xfixes:location}/lib/pkgconfig:${fixesproto:location}/lib/pkgconfig
environment =
PKG_CONFIG_PATH=${:pkg_config_depends}
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -596,8 +617,8 @@ configure-options =
[libXtst]
recipe = slapos.recipe.cmmi
shared = true
url = http://www.x.org/releases/X11R7.7/src/everything/libXtst-1.2.1.tar.bz2
md5sum = e8abc5c00c666f551cf26aa53819d592
url = https://www.x.org/releases/individual/lib/libXtst-1.2.3.tar.gz
md5sum = 2534e6015a52e0bb7b6f9148ca180028
configure-options =
--disable-specs
--disable-static
......@@ -606,7 +627,7 @@ configure-options =
--without-xsltproc
environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${libXext:location}/lib/pkgconfig:${libXext:pkg_config_depends}:${libXi:location}/lib/pkgconfig:${recordproto:location}/lib/pkgconfig
PKG_CONFIG_PATH=${libXext:location}/lib/pkgconfig:${libXext:pkg_config_depends}:${libXi:location}/lib/pkgconfig:${libXi:pkg_config_depends}:${recordproto:location}/lib/pkgconfig
[scrnsaverproto]
recipe = slapos.recipe.cmmi
......@@ -620,9 +641,18 @@ environment =
[libXScrnSaver]
recipe = slapos.recipe.cmmi
shared = true
url = https://www.x.org/releases/X11R7.7/src/everything/libXScrnSaver-1.2.2.tar.bz2
md5sum = 7a773b16165e39e938650bcc9027c1d5
url = https://www.x.org/releases/individual/lib/libXScrnSaver-1.2.3.tar.gz
md5sum = 6ae51eb64351e11cea281f3a331ac461
environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${libX11:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${scrnsaverproto:location}/lib/pkgconfig
[libXrandr]
recipe = slapos.recipe.cmmi
shared = true
url = https://www.x.org/releases/individual/lib/libXrandr-1.5.1.tar.gz
md5sum = 59e90a544ee8cf706cf11e3027339f60
pkg_config_depends = ${libX11:location}/lib/pkgconfig:${xorgproto:pkg_config_depends}:${xorgproto:location}/share/pkgconfig:${libXext:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${libXrender:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${xcbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig
environment =
PKG_CONFIG_PATH=${:pkg_config_depends}
PATH=${pkgconfig:location}/bin:%(PATH)s
......@@ -15,7 +15,7 @@
[libxcb_tmp_env.patch]
filename = libxcb_tmp_env.patch
md5sum = 03bc7279f2a37bac7bf426af213123b2
md5sum = 5a2875e62216d2f41a75e92d1bf0ae67
[xorg-server_tmp_env.patch]
filename = xorg-server_tmp_env.patch
......
Store Xorg lock files and sockets in different directories
From 8469ef2a978e19145a56adb54925cf5936ab2d49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com>
Date: Mon, 17 Sep 2018 16:07:02 +0200
Subject: [PATCH] SlapOS: Store Xorg lock files and sockets in different
directories
see xorg-server_tmp_env.patch
---
src/xcb_util.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
--- libxcb-1.7/src/xcb_util.c.back 2012-04-03 13:30:36.000000000 +0200
+++ libxcb-1.7/src/xcb_util.c 2012-04-03 14:47:00.000000000 +0200
@@ -147,11 +147,31 @@
diff --git a/src/xcb_util.c b/src/xcb_util.c
index a16270c..d05f8a1 100644
--- a/src/xcb_util.c
+++ b/src/xcb_util.c
@@ -223,15 +223,37 @@ static int _xcb_open_unix(char *protocol, const char *file);
static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen);
#endif
......@@ -27,14 +36,23 @@ see xorg-server_tmp_env.patch
+ }
+ return strncat(path_list[0], suffix, PATH_MAX);
+}
+
+
static int _xcb_open(const char *host, char *protocol, const int display)
{
int fd;
#ifdef __hpux
static const char unix_base[] = "/usr/spool/sockets/X11/";
+ #error "SlapOS: no patch for hpux"
#else
- static const char unix_base[] = "/tmp/.X11-unix/X";
- const char *base = unix_base;
+ char *base;
+ base = _xcb_getandappendcompatibleenv("XORG_LOCK_DIR", "/tmp", "/.X11-unix/X");
#endif
- const char *base = unix_base;
size_t filelen;
char *file = NULL;
int actual_filelen;
--
2.11.0
# Selenium Server test
This software release is simply to run the test suite from `../seleniumrunner/test/setup.py`
Nexedi staff can see the results of this test from the test suite
`SLAPOS-SELENIUMRUNNER-TEST` in test result module.
# THIS IS NOT A BUILDOUT FILE, despite purposedly using a compatible syntax.
# The only allowed lines here are (regexes):
# - "^#" comments, copied verbatim
# - "^[" section beginings, copied verbatim
# - lines containing an "=" sign which must fit in the following categorie.
# - "^\s*filename\s*=\s*path\s*$" where "path" is relative to this file
# Copied verbatim.
# - "^\s*hashtype\s*=.*" where "hashtype" is one of the values supported
# by the re-generation script.
# Re-generated.
# - other lines are copied verbatim
# Substitution (${...:...}), extension ([buildout] extends = ...) and
# section inheritance (< = ...) are NOT supported (but you should really
# not need these here).
[template]
filename = instance.cfg.in
md5sum = 7e75c9eccb580f278da1784941363432
[buildout]
parts =
slapos-test-runner
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration
computer = $${slap-connection:computer-id}
partition = $${slap-connection:partition-id}
url = $${slap-connection:server-url}
key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file}
[download-source]
recipe = slapos.recipe.build:gitclone
git-executable = ${git:location}/bin/git
[slapos]
<= download-source
repository = ${slapos-repository:location}
[create-directory]
recipe = slapos.cookbook:mkdirectory
bin = $${buildout:directory}/bin
working-dir = $${buildout:directory}/tmp/
[slapos-test-runner]
recipe = slapos.cookbook:wrapper
wrapper-path = $${create-directory:bin}/runTestSuite
command-line =
${buildout:bin-directory}/runTestSuite
--python_interpreter=${buildout:bin-directory}/${eggs:interpreter}
--source_code_path_list=$${slapos:location}/software/seleniumrunner/test
# XXX we need "standard" path entries to compile softwares inside test
# XXX can't we just inherit $PATH ?
environment =
PATH=${buildout:bin-directory}:/bin/:/usr/bin/
LOCAL_IPV4=$${slap-configuration:ipv4-random}
GLOBAL_IPV6=$${slap-configuration:ipv6-random}
SLAPOS_TEST_WORKING_DIR=$${create-directory:working-dir}
[buildout]
extends =
../../../../component/git/buildout.cfg
../../../../component/pillow/buildout.cfg
../../../../component/python-pynacl/buildout.cfg
../../../../component/bcrypt/buildout.cfg
../../../../stack/slapos.cfg
./buildout.hash.cfg
parts =
slapos-cookbook
eggs
template
[setup-develop-egg]
recipe = zc.recipe.egg:develop
[slapos.test.seleniumrunner-setup]
<= setup-develop-egg
egg = slapos.test.seleniumrunner
setup = ${slapos-repository:location}/software/seleniumrunner/test/
[eggs]
recipe = zc.recipe.egg
eggs =
${pillow-python:egg}
${python-pynacl:egg}
${bcrypt:egg}
${slapos.test.seleniumrunner-setup:egg}
slapos.core
entry-points =
runTestSuite=erp5.util.testsuite:runTestSuite
scripts =
runTestSuite
slapos
interpreter=
python_for_test
[git-clone-repository]
recipe = slapos.recipe.build:gitclone
git-executable = ${git:location}/bin/git
forbid-download-cache = true
branch = master
[slapos-repository]
<= git-clone-repository
repository = https://lab.nexedi.com/nexedi/slapos.git
[template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/template.cfg
mode = 640
[versions]
erp5.util = 0.4.56
slapos.recipe.template = 4.3
image = 1.5.25
Pillow = 5.3.0
selenium = 3.14.1
urllib3 = 1.23
# Django 1.11 is python 2 compatible
Django = 1.11
paramiko = 2.4.2
pyasn1 = 0.4.2
PyNaCl = 1.3.0
bcrypt = 3.1.4
\ No newline at end of file
......@@ -19,4 +19,4 @@ md5sum = c4ac5de141ae6a64848309af03e51d88
[template-selenium]
filename = instance-selenium.cfg.in
md5sum = 8f06bef6ed0737afa7916bc5ac7db537
md5sum = 4167621b473f81892d38389ac427c6ba
[buildout]
parts =
selenium-instance
promises
publish-connection-parameter
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[rootdirectory]
[fontconfig-instance]
recipe = slapos.cookbook:fontconfig
conf-path = $${directory:etc}/font.conf
font-system-folder = ${fonts:location}
font-folder = $${directory:fonts}
service-folder = $${directory:services}
[xvfb-instance]
recipe = slapos.cookbook:wrapper
wrapper-path = $${directory:services}/$${:_buildout_section_name_}
command-line =
${xserver:location}/bin/Xvfb
$${:display}
-screen 0 1024x768x24
-fbdir $${directory:framebuffer}
environment=
XORG_LOCK_DIR=$${directory:tmp}
# We can safely use any $DISPLAY, because our slapos patched X11 isolate $DISPLAYs
# by placing sockets in $XORG_LOCK_DIR and using different $XORG_LOCK_DIR per partitions.
display = :0
# For selenium server options:
# https://github.com/SeleniumHQ/selenium/wiki/Grid2#configuring-the-nodes-by-command-line
[selenium-server-hub-instance]
recipe = slapos.cookbook:wrapper
wrapper-path = $${directory:services}/$${:_buildout_section_name_}
command-line =
${java-re-8:location}/bin/java
-jar ${selenium-server:target}
-host $${:hostname}
-port $${:port}
-role hub
-maxSession 20
-newSessionWaitTimeout 600000
--debug
# newSessionWaitTimeout: let clients wait in the queue when no node are available
# maxSession: to accept enough clients
hostname = $${instance-parameter:ipv4-random}
port = 4444
base-url = http://$${:hostname}:$${:port}
url = $${:base-url}/wd/hub
register-url = $${:base-url}/grid/register/
[selenium-server-node-instance]
# Macro for a selenium server node
capabilities =
port =
java-args =
recipe = slapos.cookbook:wrapper
wrapper-path = $${directory:services}/$${:_buildout_section_name_}
command-line =
${java-re-8:location}/bin/java $${:java-args}
-jar ${selenium-server:target}
-host $${:hostname}
-port $${:port}
-role node
-timeout 300
-hub $${selenium-server-hub-instance:register-url}
-capabilities $${:capabilities}
--debug
# browsers and drivers are in buildout bin-directory, so we add that directory to to $PATH
environment =
PATH=${buildout:bin-directory}
XORG_LOCK_DIR=$${directory:tmp}
DISPLAY=$${xvfb-instance:display}
FONTCONFIG_FILE=$${fontconfig-instance:conf-path}
hostname = $${instance-parameter:ipv4-random}
[selenium-server-node-instance-firefox-52]
<= selenium-server-node-instance
capabilities = browserName=firefox,maxInstances=3,marionette=true,platform=LINUX,version=${firefox-52:version},firefox_binary=${firefox-wrapper-52:location}
java-args = -Dwebdriver.gecko.driver=${geckodriver-0.16.1:location}
port = 7777
[selenium-server-node-instance-firefox-60]
<= selenium-server-node-instance
capabilities = browserName=firefox,maxInstances=3,marionette=true,platform=LINUX,version=${firefox-60:version},firefox_binary=${firefox-wrapper-60:location}
java-args = -Dwebdriver.gecko.driver=${geckodriver-0.22.0:location}
port = 7778
[selenium-server-node-instance-chromium-69]
<= selenium-server-node-instance
capabilities = browserName=chrome,maxInstances=3,platform=LINUX,version=${chromium-69:version},chrome_binary=${chromium-wrapper-69:location}
java-args = -Dwebdriver.chrome.driver=${chromedriver-wrapper-2.41:location}
port = 7779
[selenium-server-admin-password]
recipe = slapos.cookbook:generate.password
username = admin
bytes = 12
[selenium-server-selenium-password]
recipe = slapos.cookbook:generate.password
username = selenium
bytes = 12
[selenium-server-frontend-config]
recipe = slapos.recipe.template:jinja2
rendered = $${directory:etc}/$${:_buildout_section_name_}
template = inline:
https://$${:hostname}:$${:port} {
bind $${:ip}
tls self_signed # TODO
proxy / $${selenium-server-hub-instance:base-url} {
transparent
}
basicauth $${selenium-server-admin-password:username} $${selenium-server-admin-password:passwd} {
realm "Grid Admin"
$${:path-admin}
}
basicauth $${selenium-server-selenium-password:username} $${selenium-server-selenium-password:passwd} {
realm "Selenium Server"
$${:path-hub}
}
}
ip = $${instance-parameter:ipv6-random}
hostname = [$${:ip}]
port = 9443
path-admin = /grid/console
path-hub = /wd/hub
[selenium-server-frontend-instance]
recipe = slapos.cookbook:wrapper
wrapper-path = $${directory:services}/$${:_buildout_section_name_}
command-line =
${caddy:output} -conf $${selenium-server-frontend-config:rendered}
ip = $${selenium-server-frontend-config:ip}
hostname = $${selenium-server-frontend-config:hostname}
port = $${selenium-server-frontend-config:port}
admin-url = https://$${selenium-server-admin-password:username}:$${selenium-server-admin-password:passwd}@$${:hostname}:$${:port}$${selenium-server-frontend-config:path-admin}
url = https://$${selenium-server-selenium-password:username}:$${selenium-server-selenium-password:passwd}@$${:hostname}:$${:port}$${selenium-server-frontend-config:path-hub}
[userinfo]
recipe = slapos.cookbook:userinfo
[sshd-address]
recipe = slapos.cookbook:free_port
minimum = 22222
maximum = 22231
ip = $${slap-network-information:global-ipv6}
hostname = $${:ip}
[ssh-keygen-base]
recipe = plone.recipe.command
output = $${directory:etc}/$${:_buildout_section_name_}
command = ${openssh-output:keygen} -f $${:output} -N '' $${:extra-args}
[ssh-host-rsa-key]
<=ssh-keygen-base
extra-args=-t rsa
[ssh-host-dsa-key]
<=ssh-keygen-base
extra-args=-t dsa
[ssh-host-ecdsa-key]
<=ssh-keygen-base
extra-args=-t ecdsa -b 521
[sshd-config]
recipe = slapos.recipe.template:jinja2
rendered = $${directory:etc}/sshd.conf
path_pid = $${directory:run}/sshd.pid
template = inline:
PidFile $${:path_pid}
Port $${sshd-address:port}
ListenAddress $${sshd-address:ip}
Protocol 2
UsePrivilegeSeparation no
HostKey $${ssh-host-rsa-key:output}
HostKey $${ssh-host-dsa-key:output}
HostKey $${ssh-host-ecdsa-key:output}
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile $${sshd-authorized-key:authorized-keys-file}
ClientAliveInterval 30
ClientAliveCountMax 10
ForceCommand echo "Welcome to SlapOS Selenium Server."; ${coreutils:location}/bin/sleep infinity
[sshd-service]
recipe = slapos.cookbook:wrapper
command-line = ${openssh:location}/sbin/sshd -D -e -f $${sshd-config:rendered}
wrapper-path = $${directory:services}/$${:_buildout_section_name_}
username = $${userinfo:pw-name}
ip = $${sshd-address:ip}
port = $${sshd-address:port}
url = ssh://$${:username}@[$${:ip}]:$${:port}
[sshd-authorized-key]
recipe = plone.recipe.command
stop-on-error = true
location = $${buildout:directory}/.ssh
authorized-keys-file = $${:location}/authorized_keys
command = mkdir -p $${:location} && echo '$${instance-parameter:configuration.ssh-authorized-key}' > $${:authorized-keys-file}
[promises]
recipe =
instance-promises =
$${sshd-listen-promise:path}
$${selenium-server-frontend-listen-promise:path}
$${selenium-server-hub-listen-promise:path}
$${selenium-server-node-firefox-52-listen-promise:path}
$${selenium-server-node-firefox-60-listen-promise:path}
$${selenium-server-node-instance-chromium-69-listen-promise:path}
[check-port-listening-promise]
recipe = slapos.cookbook:check_port_listening
path = $${directory:promises}/$${:_buildout_section_name_}
[sshd-listen-promise]
<= check-port-listening-promise
hostname = $${sshd-address:hostname}
port = $${sshd-address:port}
[selenium-server-frontend-listen-promise]
<= check-port-listening-promise
hostname = $${selenium-server-frontend-instance:ip}
port = $${selenium-server-frontend-instance:port}
[selenium-server-hub-listen-promise]
<= check-port-listening-promise
hostname = $${selenium-server-hub-instance:hostname}
port = $${selenium-server-hub-instance:port}
[selenium-server-node-firefox-52-listen-promise]
<= check-port-listening-promise
hostname = $${selenium-server-node-instance-firefox-52:hostname}
port = $${selenium-server-node-instance-firefox-52:port}
[selenium-server-node-firefox-60-listen-promise]
<= check-port-listening-promise
hostname = $${selenium-server-node-instance-firefox-60:hostname}
port = $${selenium-server-node-instance-firefox-60:port}
[selenium-server-node-instance-chromium-69-listen-promise]
<= check-port-listening-promise
hostname = $${selenium-server-node-instance-chromium-69:hostname}
port = $${selenium-server-node-instance-chromium-69:port}
[publish-connection-parameter]
recipe = slapos.cookbook:publish
backend-url = $${selenium-server-hub-instance:url}
url = $${selenium-server-frontend-instance:url}
admin-url = $${selenium-server-frontend-instance:admin-url}
ssh-url = $${sshd-service:url}
# to run a local node - useful to see what tests are doing or
# using to use unsupported browsers like safari or edge or to test
# on mobile using appium.
# $PORT must be free on both hosts, different clients must use different ports.
run-node-command = PORT=7999 bash -c 'trap '"'"'kill -TERM $SSHPID; wait $SSHPID '"'"' TERM INT; ssh -L 4444:$${selenium-server-hub-instance:hostname}:$${selenium-server-hub-instance:port} -R $PORT:127.0.0.1:$PORT -p $${sshd-service:port} $${sshd-service:username}@$${sshd-service:ip} & SSHPID=$!; java -jar selenium-server-standalone-3.14.0.jar -role node -host 127.0.0.1 -port $PORT ; wait "$SSHPID"'
[instance-parameter]
recipe = slapos.cookbook:slapconfiguration
computer = $${slap-connection:computer-id}
partition = $${slap-connection:partition-id}
url = $${slap-connection:server-url}
key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file}
# A ssh public key, as found in ~/.ssh/authorized_keys
# multiple keys can be given, indented in a buildout compatible format (mmmh)
configuration.ssh-authorized-key =
[directory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
var = $${buildout:directory}/var
srv = $${buildout:directory}/srv
bin = $${buildout:directory}/bin
tmp = $${buildout:directory}/tmp
[basedirectory]
recipe = slapos.cookbook:mkdirectory
services = $${rootdirectory:etc}/run
run = $${rootdirectory:var}/run
framebuffer = $${rootdirectory:srv}/framebuffer
services = $${:etc}/service
promises = $${:etc}/promise
framebuffer = $${:srv}/framebuffer
fonts = $${:srv}/fonts/
ssh = $${:etc}/ssh
run = $${:var}/run
\ No newline at end of file
# Selenium server
# https://seleniumhq.github.io/docs/grid.html
[buildout]
extends =
../../component/xorg/buildout.cfg
../../component/lxml-python/buildout.cfg
../../component/firefox/buildout.cfg
../../component/dash/buildout.cfg
../../component/chromium/buildout.cfg
../../component/chromedriver/buildout.cfg
../../component/coreutils/buildout.cfg
../../component/java/buildout.cfg
../../component/caddy/buildout.cfg
../../component/openssh/buildout.cfg
../../stack/slapos.cfg
./buildout.hash.cfg
# develop += /opt/slapdev
parts =
slapos-cookbook
template
eggs
instance-recipe-egg
xserver
firefox-wrapper
geckodriver
xwd
[instance-recipe]
egg = slapos.cookbook
module = seleniumrunner
[instance-recipe-egg]
recipe = zc.recipe.egg
eggs = ${instance-recipe:egg}
[eggs]
recipe = zc.recipe.egg
eggs =
${lxml-python:egg}
[selenium-server]
recipe = slapos.recipe.build:download
version = 3.14.0
md5sum = 376450bd517510442b60018646deadfe
filename = selenium-server-standalone-${:version}.jar
url = https://selenium-release.storage.googleapis.com/3.14/${:filename}
[macro-template]
recipe = slapos.recipe.template
......
Tests for SeleniumRunner software release
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 3
# of the License, or (at your option) any later version.
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from setuptools import setup, find_packages
version = '0.0.1.dev0'
name = 'slapos.test.seleniumrunner'
long_description = open("README.md").read()
setup(name=name,
version=version,
description="Test for SlapOS' Seleniumrunner",
long_description=long_description,
long_description_content_type='text/markdown',
maintainer="Nexedi",
maintainer_email="info@nexedi.com",
url="https://lab.nexedi.com/nexedi/slapos",
packages=find_packages(),
install_requires=[
'slapos.core',
'supervisor',
'slapos.libnetworkcache',
'erp5.util',
'selenium',
'psutil',
'image',
'requests',
'paramiko',
],
zip_safe=True,
test_suite='test',
)
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 3
# of the License, or (at your option) any later version.
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import cgi
import json
import multiprocessing
import os
import tempfile
import unittest
import urlparse
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from io import BytesIO
import paramiko
import requests
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from utils import SlapOSInstanceTestCase, findFreeTCPPort
debug_mode = os.environ.get('DEBUG')
# for development: debugging logs and install Ctrl+C handler
if debug_mode:
import logging
logging.basicConfig(level=logging.DEBUG)
unittest.installHandler()
class WebServerMixin(object):
"""Mixin class which provides a simple web server reachable at self.server_url
"""
def setUp(self):
"""Start a minimal web server.
"""
class TestHandler(BaseHTTPRequestHandler):
"""Request handler for our test server.
The implemented server is:
- submit q and you'll get a page with q as title
- upload a file and the file content will be displayed in div.uploadedfile
"""
def log_message(self, *args, **kw):
if debug_mode:
BaseHTTPRequestHandler.log_message(self, *args, **kw)
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write('''
<html>
<title>Test page</title>
<body>
<form action="/" method="POST" enctype="multipart/form-data">
<input name="q" type="text"></input>
<input name="f" type="file" ></input>
<input type="submit" value="I'm feeling lucky"></input>
</form>
</body>
</html>''')
def do_POST(self):
form = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={'REQUEST_METHOD':'POST',
'CONTENT_TYPE':self.headers['Content-Type'],})
self.send_response(200)
self.end_headers()
file_data = 'no file'
if form.has_key('f'):
file_data = form['f'].file.read()
self.wfile.write('''
<html>
<title>%s</title>
<div>%s</div>
</html>
''' % (form['q'].value, file_data))
super(WebServerMixin, self).setUp()
ip = os.environ.get('LOCAL_IPV4', '127.0.1.1')
port = findFreeTCPPort(ip)
server = HTTPServer((ip, port), TestHandler)
self.server_process = multiprocessing.Process(target=server.serve_forever)
self.server_process.start()
self.server_url = 'http://%s:%s/' % (ip, port)
def tearDown(self):
self.server_process.terminate()
self.server_process.join()
super(WebServerMixin, self).tearDown()
class BrowserCompatibilityMixin(WebServerMixin):
"""Mixin class to run validation tests on a specific browser
"""
desired_capabilities = NotImplemented
user_agent = NotImplemented
def setUp(self):
super(BrowserCompatibilityMixin, self).setUp()
self.driver = webdriver.Remote(
command_executor=self.computer_partition.getConnectionParameterDict()['backend-url'],
desired_capabilities=self.desired_capabilities)
def tearDown(self):
self.driver.quit()
super(BrowserCompatibilityMixin, self).tearDown()
def test_user_agent(self):
self.assertIn(
self.user_agent,
self.driver.execute_script('return navigator.userAgent'))
def test_simple_submit_scenario(self):
self.driver.get(self.server_url)
input_element = WebDriverWait(self.driver, 3).until(
EC.visibility_of_element_located((By.NAME, 'q')))
input_element.send_keys(self.id())
input_element.submit()
WebDriverWait(self.driver, 3).until(EC.title_is(self.id()))
def test_upload_file(self):
f = tempfile.NamedTemporaryFile(delete=False)
f.write(self.id())
f.close()
self.addCleanup(lambda: os.remove(f.name))
self.driver.get(self.server_url)
self.driver.find_element_by_xpath('//input[@name="f"]').send_keys(f.name)
self.driver.find_element_by_xpath('//input[@type="submit"]').click()
self.assertEqual(
self.id(),
self.driver.find_element_by_xpath('//div').text)
def test_screenshot(self):
self.driver.get(self.server_url)
screenshot = Image.open(BytesIO(self.driver.get_screenshot_as_png()))
# just check it's not a white screen
self.assertGreater(len(screenshot.getcolors(maxcolors=512)), 2)
def test_window_and_screen_size(self):
size = json.loads(self.driver.execute_script('''
return JSON.stringify({
'screen.width': window.screen.width,
'screen.height': window.screen.height,
'screen.pixelDepth': window.screen.pixelDepth,
'innerWidth': window.innerWidth,
'innerHeight': window.innerHeight
})'''))
# Xvfb is configured like this
self.assertEqual(1024, size['screen.width'])
self.assertEqual(768, size['screen.height'])
self.assertEqual(24, size['screen.pixelDepth'])
# window size must not be 0 (wrong firefox integration report this)
self.assertGreater(size['innerWidth'], 0)
self.assertGreater(size['innerHeight'], 0)
def test_resize_window(self):
self.driver.set_window_size(800, 900)
size = json.loads(self.driver.execute_script('''
return JSON.stringify({
'outerWidth': window.outerWidth,
'outerHeight': window.outerHeight
})'''))
self.assertEqual(800, size['outerWidth'])
self.assertEqual(900, size['outerHeight'])
def test_multiple_clients(self):
parameter_dict = self.computer_partition.getConnectionParameterDict()
webdriver_url = parameter_dict['backend-url']
queue = multiprocessing.Queue()
def _test(q, server_url):
driver = webdriver.Remote(
command_executor=webdriver_url,
desired_capabilities=self.desired_capabilities)
try:
driver.get(server_url)
q.put(driver.title == 'Test page')
finally:
driver.quit()
nb_workers = 10
workers = []
for i in range(nb_workers):
worker = multiprocessing.Process(
target=_test,
args=(queue, self.server_url))
worker.start()
workers.append(worker)
del worker # pylint
_ = [worker.join(timeout=30) for worker in workers]
# terminate workers if they are still alive after 30 seconds
_ = [worker.terminate() for worker in workers if worker.is_alive()]
_ = [worker.join() for worker in workers]
del _ # pylint
self.assertEqual(
[True] * nb_workers,
[queue.get() for _ in range(nb_workers)])
class SeleniumServerTestCase(SlapOSInstanceTestCase):
"""Test the remote driver on a minimal web server.
"""
@classmethod
def getSoftwareURLList(cls):
return (os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'software.cfg')), )
class TestBrowserSelection(WebServerMixin, SeleniumServerTestCase):
"""Test browser can be selected by `desiredCapabilities``
"""
def test_chrome(self):
parameter_dict = self.computer_partition.getConnectionParameterDict()
webdriver_url = parameter_dict['backend-url']
driver = webdriver.Remote(
command_executor=webdriver_url,
desired_capabilities=DesiredCapabilities.CHROME)
driver.get(self.server_url)
self.assertEqual('Test page', driver.title)
self.assertIn(
'Chrome',
driver.execute_script('return navigator.userAgent'))
self.assertNotIn(
'Firefox',
driver.execute_script('return navigator.userAgent'))
driver.quit()
def test_firefox(self):
parameter_dict = self.computer_partition.getConnectionParameterDict()
webdriver_url = parameter_dict['backend-url']
driver = webdriver.Remote(
command_executor=webdriver_url,
desired_capabilities=DesiredCapabilities.FIREFOX)
driver.get(self.server_url)
self.assertEqual('Test page', driver.title)
self.assertIn(
'Firefox',
driver.execute_script('return navigator.userAgent'))
driver.quit()
def test_firefox_desired_version(self):
parameter_dict = self.computer_partition.getConnectionParameterDict()
webdriver_url = parameter_dict['backend-url']
desired_capabilities = DesiredCapabilities.FIREFOX.copy()
desired_capabilities['version'] = '60.0.2esr'
driver = webdriver.Remote(
command_executor=webdriver_url,
desired_capabilities=desired_capabilities)
self.assertIn(
'Gecko/20100101 Firefox/60.0',
driver.execute_script('return navigator.userAgent'))
driver.quit()
desired_capabilities['version'] = '52.9.0esr'
driver = webdriver.Remote(
command_executor=webdriver_url,
desired_capabilities=desired_capabilities)
self.assertIn(
'Gecko/20100101 Firefox/52.0',
driver.execute_script('return navigator.userAgent'))
driver.quit()
class TestFrontend(WebServerMixin, SeleniumServerTestCase):
"""Test hub's https frontend.
"""
def test_admin(self):
parameter_dict = self.computer_partition.getConnectionParameterDict()
admin_url = parameter_dict['admin-url']
parsed = urlparse.urlparse(admin_url)
self.assertEqual('admin', parsed.username)
self.assertTrue(parsed.password)
self.assertIn(
'Grid Console',
requests.get(admin_url, verify=False).text)
def test_browser_use_hub(self):
parameter_dict = self.computer_partition.getConnectionParameterDict()
webdriver_url = parameter_dict['url']
parsed = urlparse.urlparse(webdriver_url)
self.assertEqual('selenium', parsed.username)
self.assertTrue(parsed.password)
driver = webdriver.Remote(
command_executor=webdriver_url,
desired_capabilities=DesiredCapabilities.CHROME)
driver.get(self.server_url)
self.assertEqual('Test page', driver.title)
driver.quit()
class TestSSHServer(SeleniumServerTestCase):
@classmethod
def getInstanceParameterDict(cls):
cls.ssh_key = paramiko.RSAKey.generate(1024)
return {'ssh-authorized-key': 'ssh-rsa {}'.format(cls.ssh_key.get_base64())}
def test_connect(self):
parameter_dict = self.computer_partition.getConnectionParameterDict()
ssh_url = parameter_dict['ssh-url']
parsed = urlparse.urlparse(ssh_url)
self.assertEqual('ssh', parsed.scheme)
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.client.WarningPolicy)
client.connect(
username=urlparse.urlparse(ssh_url).username,
hostname=urlparse.urlparse(ssh_url).hostname,
port=urlparse.urlparse(ssh_url).port,
pkey=self.ssh_key,
)
channel = client.invoke_shell()
channel.settimeout(30)
# openssh prints a warning 'Attempt to write login records by non-root user (aborting)'
# so we received more than the lenght of the asserted message.
self.assertIn("Welcome to SlapOS Selenium Server.", channel.recv(100))
class TestFirefox52(BrowserCompatibilityMixin, SeleniumServerTestCase):
desired_capabilities = dict(DesiredCapabilities.FIREFOX, version='52.9.0esr')
user_agent = 'Gecko/20100101 Firefox/52.0'
# resizing window is not supported on firefox 52 geckodriver
test_resize_window = unittest.expectedFailure(
BrowserCompatibilityMixin.test_resize_window)
class TestFirefox60(BrowserCompatibilityMixin, SeleniumServerTestCase):
desired_capabilities = dict(DesiredCapabilities.FIREFOX, version='60.0.2esr')
user_agent = 'Gecko/20100101 Firefox/60.0'
class TestChrome69(BrowserCompatibilityMixin, SeleniumServerTestCase):
desired_capabilities = dict(DesiredCapabilities.CHROME, version='69.0.3497.0')
user_agent = 'Chrome/69.0.3497.0'
##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 3
# of the License, or (at your option) any later version.
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import unittest
import os
import socket
from contextlib import closing
import logging
import StringIO
import xmlrpclib
import supervisor.xmlrpc
from erp5.util.testnode.SlapOSControler import SlapOSControler
from erp5.util.testnode.ProcessManager import ProcessManager
# Utility functions
def findFreeTCPPort(ip=''):
"""Find a free TCP port to listen to.
"""
family = socket.AF_INET6 if ':' in ip else socket.AF_INET
with closing(socket.socket(family, socket.SOCK_STREAM)) as s:
s.bind((ip, 0))
return s.getsockname()[1]
# TODO:
# - allow requesting multiple instances ?
class SlapOSInstanceTestCase(unittest.TestCase):
"""Install one slapos instance.
This test case install software(s) and request one instance during `setUpClass`
and destroy the instance during `tearDownClass`.
Software Release URL, Instance Software Type and Instance Parameters can be defined
on the class.
All tests from the test class will run with the same instance.
The following class attributes are available:
* `computer_partition`: the `slapos.core.XXX` computer partition instance.
* `computer_partition_root_path`: the path of the instance root directory,
"""
# Methods to be defined by subclasses.
@classmethod
def getSoftwareURLList(cls):
"""Return URL of software releases to install.
To be defined by subclasses.
"""
raise NotImplementedError()
@classmethod
def getInstanceParameterDict(cls):
"""Return instance parameters
To be defined by subclasses if they need to request instance with specific
parameters.
"""
return {}
@classmethod
def getInstanceSoftwareType(cls):
"""Return software type for instance, default "default"
To be defined by subclasses if they need to request instance with specific
software type.
"""
return "default"
# Utility methods.
def getSupervisorRPCServer(self):
"""Returns a XML-RPC connection to the supervisor used by slapos node
Refer to http://supervisord.org/api.html for details of available methods.
"""
# xmlrpc over unix socket https://stackoverflow.com/a/11746051/7294664
return xmlrpclib.ServerProxy(
'http://slapos-supervisor',
transport=supervisor.xmlrpc.SupervisorTransport(
None,
None,
# XXX hardcoded socket path
serverurl="unix://{working_directory}/inst/supervisord.socket".format(
**self.config)))
# Unittest methods
@classmethod
def setUpClass(cls):
"""Setup the class, build software and request an instance.
If you have to override this method, do not forget to call this method on
parent class.
"""
try:
cls.setUpWorkingDirectory()
cls.setUpConfig()
cls.setUpSlapOSController()
cls.runSoftwareRelease()
# XXX instead of "runSoftwareRelease", it would be better to be closer to slapos usage:
# cls.supplySoftwares()
# cls.installSoftwares()
cls.runComputerPartition()
# XXX instead of "runComputerPartition", it would be better to be closer to slapos usage:
# cls.requestInstances()
# cls.createInstances()
# cls.requestInstances()
except BaseException:
cls.stopSlapOSProcesses()
cls.setUp = lambda self: self.fail('Setup Class failed.')
raise
@classmethod
def tearDownClass(cls):
"""Tear down class, stop the processes and destroy instance.
"""
cls.stopSlapOSProcesses()
# Implementation
@classmethod
def stopSlapOSProcesses(cls):
if hasattr(cls, '_process_manager'):
cls._process_manager.killPreviousRun()
@classmethod
def setUpWorkingDirectory(cls):
"""Initialise the directories"""
cls.working_directory = os.environ.get(
'SLAPOS_TEST_WORKING_DIR',
os.path.join(os.path.dirname(__file__), '.slapos'))
# To prevent error: Cannot open an HTTP server: socket.error reported
# AF_UNIX path too long This `working_directory` should not be too deep.
# Socket path is 108 char max on linux
# https://github.com/torvalds/linux/blob/3848ec5/net/unix/af_unix.c#L234-L238
# Supervisord socket name contains the pid number, which is why we add
# .xxxxxxx in this check.
if len(cls.working_directory + '/inst/supervisord.socket.xxxxxxx') > 108:
raise RuntimeError('working directory ( {} ) is too deep, try setting '
'SLAPOS_TEST_WORKING_DIR'.format(cls.working_directory))
if not os.path.exists(cls.working_directory):
os.mkdir(cls.working_directory)
@classmethod
def setUpConfig(cls):
"""Create slapos configuration"""
cls.config = {
"working_directory": cls.working_directory,
"slapos_directory": cls.working_directory,
"log_directory": cls.working_directory,
"computer_id": 'slapos.test', # XXX
'proxy_database': os.path.join(cls.working_directory, 'proxy.db'),
'partition_reference': cls.__name__,
# "proper" slapos command must be in $PATH
'slapos_binary': 'slapos',
}
# Some tests are expecting that local IP is not set to 127.0.0.1
ipv4_address = os.environ.get('LOCAL_IPV4', '127.0.1.1')
ipv6_address = os.environ['GLOBAL_IPV6']
cls.config['proxy_host'] = cls.config['ipv4_address'] = ipv4_address
cls.config['ipv6_address'] = ipv6_address
cls.config['proxy_port'] = findFreeTCPPort(ipv4_address)
cls.config['master_url'] = 'http://{proxy_host}:{proxy_port}'.format(
**cls.config)
@classmethod
def setUpSlapOSController(cls):
"""Create the a "slapos controller" and supply softwares from `getSoftwareURLList`.
This is equivalent to:
slapos proxy start
for sr in getSoftwareURLList; do
slapos supply $SR $COMP
done
"""
cls._process_manager = ProcessManager()
# XXX this code is copied from testnode code
cls.slapos_controler = SlapOSControler(
cls.working_directory,
cls.config
)
slapproxy_log = os.path.join(cls.config['log_directory'], 'slapproxy.log')
logger = logging.getLogger(__name__)
logger.debug('Configured slapproxy log to %r', slapproxy_log)
cls.software_url_list = cls.getSoftwareURLList()
cls.slapos_controler.initializeSlapOSControler(
slapproxy_log=slapproxy_log,
process_manager=cls._process_manager,
reset_software=False,
software_path_list=cls.software_url_list)
# XXX we should check *earlier* if that pidfile exist and if supervisord
# process still running, because if developer started supervisord (or bugs?)
# then another supervisord will start and starting services a second time
# will fail.
cls._process_manager.supervisord_pid_file = os.path.join(
cls.slapos_controler.instance_root, 'var', 'run', 'supervisord.pid')
@classmethod
def runSoftwareRelease(cls):
"""Run all the software releases that were supplied before.
This is the equivalent of `slapos node software`.
The tests will be marked file if software building fail.
"""
logger = logging.getLogger()
logger.level = logging.DEBUG
stream = StringIO.StringIO()
stream_handler = logging.StreamHandler(stream)
logger.addHandler(stream_handler)
try:
cls.software_status_dict = cls.slapos_controler.runSoftwareRelease(
cls.config, environment=os.environ)
stream.seek(0)
stream.flush()
message = ''.join(stream.readlines()[-100:])
assert cls.software_status_dict['status_code'] == 0, message
finally:
logger.removeHandler(stream_handler)
del stream
@classmethod
def runComputerPartition(cls):
"""Instanciate the software.
This is the equivalent of doing:
slapos request --type=getInstanceSoftwareType --parameters=getInstanceParameterDict
slapos node instance
and return the slapos request instance parameters.
This can be called by tests to simulate re-request with different parameters.
"""
logger = logging.getLogger()
logger.level = logging.DEBUG
stream = StringIO.StringIO()
stream_handler = logging.StreamHandler(stream)
logger.addHandler(stream_handler)
if cls.getInstanceSoftwareType() != 'default':
raise NotImplementedError
instance_parameter_dict = cls.getInstanceParameterDict()
try:
cls.instance_status_dict = cls.slapos_controler.runComputerPartition(
cls.config,
cluster_configuration=instance_parameter_dict,
environment=os.environ)
stream.seek(0)
stream.flush()
message = ''.join(stream.readlines()[-100:])
assert cls.instance_status_dict['status_code'] == 0, message
finally:
logger.removeHandler(stream_handler)
del stream
# FIXME: similar to test node, only one (root) partition is really
# supported for now.
computer_partition_list = []
for i in range(len(cls.software_url_list)):
computer_partition_list.append(
cls.slapos_controler.slap.registerOpenOrder().request(
cls.software_url_list[i],
# This is how testnode's SlapOSControler name created partitions
partition_reference='testing partition {i}'.format(
i=i, **cls.config),
partition_parameter_kw=instance_parameter_dict))
# expose some class attributes so that tests can use them:
# the ComputerPartition instances, to getInstanceParameterDict
cls.computer_partition = computer_partition_list[0]
# the path of the instance on the filesystem, for low level inspection
cls.computer_partition_root_path = os.path.join(
cls.config['working_directory'],
'inst',
cls.computer_partition.getId())
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment