Commit 165ffcde authored by Romain Courteaud's avatar Romain Courteaud

jstestnode: new software to automate jio/renderjs test execution

This software release install all git repositories, firefox, nginx and nodejs.
It configure jio/renderjs development environnment.
Finally, it provides a runTestSuite script to easily publish results in ERP5.

Firefox is controlled with Selenium WebDriver, to launch qunit tests and parse results.
parent ed20e07d
[buildout]
parts =
nginx-service
runTestSuite-instance
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[publish]
recipe = slapos.cookbook:publish
nginx = http://[$${nginx-configuration:ip}]:$${nginx-configuration:port}/
[directory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
bin = $${buildout:directory}/bin
srv = $${buildout:directory}/srv
var = $${buildout:directory}/var
run = $${:var}/run
log = $${:var}/log
varnginx = $${:var}/nginx
scripts = $${:etc}/run
services = $${:etc}/service
promise = $${:etc}/promise/
www = $${:srv}/www
home = $${:etc}/home
ssl = $${:etc}/ssl
framebuffer = $${:srv}/framebuffer
#################################
# Firefox
#################################
[runTestSuite-instance]
recipe = slapos.recipe.template
url = ${template-runTestSuite:output}
output = $${directory:bin}/runTestSuite
mode = 0700
[firefox-instance]
recipe = slapos.cookbook:firefox
executable = firefox
runner-path = $${directory:bin}/$${:executable}
firefox-path = ${firefox:location}/firefox-slapos
prefsjs-path = $${directory:etc}/prefs.js
shell-path = ${dash:location}/bin/dash
tmp-path = $${xvfb-instance:tmp-path}
[xvfb-instance]
recipe = slapos.cookbook:xvfb
runner-path = $${directory:services}/xvfb
xvfb-path = ${xserver:location}/bin/Xvfb
fbdir-path = $${directory:framebuffer}
tmp-path = $${directory:run}
shell-path = ${dash:location}/bin/dash
xwd-path = ${xwd:location}/bin/xwd
xwd-hook-path = $${directory:bin}/xwd
#################################
# Nginx service
#################################
[nginx-service]
recipe = slapos.recipe.template
url = ${template-nginx-service:output}
output = $${directory:services}/nginx
mode = 0700
virtual-depends =
$${nginx-configuration:ip}
[nginx-configuration]
recipe = slapos.recipe.template
url = ${template-nginx-configuration:output}
output = $${directory:etc}/nginx.cfg
mode = 0600
access_log = $${directory:log}/nginx-access.log
error_log = $${directory:log}/nginx-error.log
ip = $${instance-parameter:ipv6-random}
port = 9443
ssl_key = $${directory:ssl}/nginx.key
ssl_csr = $${directory:ssl}/nginx.csr
ssl_crt = $${directory:ssl}/nginx.crt
#################################
# SlapOS service
#################################
[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}
\ No newline at end of file
#!${buildout:directory}/bin/${eggs:interpreter}
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
"""
Script to run jIO/renderJS test suite using Nexedi's test node framework.
"""
import argparse, os, re, shutil, subprocess, sys, traceback
from erp5.util import taskdistribution
from time import gmtime, strftime
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Put a 'firefox' executable in the path
# otherwise, WebDriver refuses to start
os.environ['PATH'] = '$${directory:bin}' + os.pathsep + os.environ['PATH']
FIREFOX_EXECUTABLE = '$${firefox-instance:executable}'
BASE_URL = 'http://[$${nginx-configuration:ip}]:$${nginx-configuration:port}/'
def main():
parser = argparse.ArgumentParser(description='Run a test suite.')
parser.add_argument('--test_suite', help='The test suite name')
parser.add_argument('--test_suite_title', help='The test suite title')
parser.add_argument('--test_node_title', help='The test node title')
parser.add_argument('--project_title', help='The project title')
parser.add_argument('--revision', help='The revision to test',
default='dummy_revision')
parser.add_argument('--master_url',
help='The Url of Master controling many suites')
args = parser.parse_args()
test_suite_title = args.test_suite_title or args.test_suite
revision = args.revision
test_line_dict = {}
if ('jio' in test_suite_title):
url = BASE_URL + '/jio/test/tests.html'
else:
url = BASE_URL + '/renderjs/test/'
date = strftime("%Y/%m/%d %H:%M:%S", gmtime())
##########################
# Run all tests
##########################
try:
firefox_binary = webdriver.firefox.firefox_binary.FirefoxBinary(firefox_path=FIREFOX_EXECUTABLE)
browser = webdriver.Firefox(firefox_binary=firefox_binary)
agent = browser.execute_script("return navigator.userAgent")
print agent
browser.get(url)
WebDriverWait(browser, 60).until(EC.presence_of_element_located((
By.XPATH, '//p[@id="qunit-testresult" and contains(text(), "completed")]')
))
browser.title.encode('UTF-8')
print browser.find_element_by_id("qunit-testresult").text
for elt in browser.find_elements_by_xpath('//ol[@id="qunit-tests"]/li'):
test_name = '%s: %s' % (
elt.find_element_by_xpath('.//span[@class="module-name"]').text,
elt.find_element_by_xpath('.//span[@class="test-name"]').text
)
print elt.get_attribute('class'), elt.find_element_by_tag_name('strong').text
# print elt.find_element_by_tag_name('ol').get_attribute('innerHTML')
failure = int(elt.find_element_by_xpath('.//b[@class="failed"]').text)
success = int(elt.find_element_by_xpath('.//b[@class="passed"]').text)
test_line_dict[test_name] = {
'test_count': success + failure,
'error_count': 0,
'failure_count': failure,
'skip_count': 0,
'duration': elt.find_element_by_xpath('.//span[@class="runtime"]').text,
'date': date,
'command': elt.find_element_by_xpath('.//a[text()="Rerun"]').get_attribute('href'),
'stdout': agent,
'stderr': '',
'html_test_result': elt.find_element_by_tag_name('ol').get_attribute('innerHTML')
}
browser.quit()
except Exception:
# Catch any exception here, to warn user instead of being silent,
# by generating fake error result
result = dict(status_code=-1,
command=url,
stderr=traceback.format_exc(),
stdout='')
# XXX: inform test node master of error
raise EnvironmentError(result)
tool = taskdistribution.TaskDistributionTool(portal_url=args.master_url)
test_result = tool.createTestResult(revision = revision,
test_name_list = test_line_dict.keys(),
node_title = args.test_node_title,
test_title = test_suite_title,
project_title = args.project_title)
if test_result is None:
return
# report test results
while 1:
test_result_line = test_result.start()
if not test_result_line:
break
# report status back to Nexedi ERP5
test_result_line.stop(**test_line_dict[test_result_line.name])
if __name__ == "__main__":
main()
\ No newline at end of file
[buildout]
extends =
../../stack/slapos.cfg
../../stack/nodejs.cfg
../../component/git/buildout.cfg
../../component/xorg/buildout.cfg
../../component/firefox/buildout.cfg
../../component/dash/buildout.cfg
../../component/nginx/buildout.cfg
../../component/openssl/buildout.cfg
parts =
slapos-cookbook
nodejs
git
eggs
xserver
firefox
xwd
renderjs-install
jio-install
nginx
openssl
instance
[instance]
recipe = slapos.recipe.template
md5sum = 25a9c895fff279b71b0dbbad6647181b
url = ${:_profile_base_location_}/instance.cfg.in
output = ${buildout:directory}/instance.cfg
mode = 0644
[eggs]
recipe = zc.recipe.egg
eggs =
erp5.util
selenium
interpreter = pythonwitheggs
[renderjs-repository.git]
recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/nexedi/renderjs.git
branch = master
git-executable = ${git:location}/bin/git
develop = true
[renderjs-install]
recipe = plone.recipe.command
stop-on-error = true
command = cd ${renderjs-repository.git:location} && PATH=${git:location}/bin/:${nodejs:location}/bin/:$PATH ${nodejs:location}/bin/npm install .
update_command = ${:command}
[jio-repository.git]
recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/nexedi/jio.git
branch = master
git-executable = ${git:location}/bin/git
develop = true
[jio-install]
recipe = plone.recipe.command
stop-on-error = true
command = cd ${jio-repository.git:location} && PATH=${git:location}/bin/:${nodejs:location}/bin/:$PATH ${nodejs:location}/bin/npm install .
update_command = ${:command}
[rsvp-repository.git]
recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/nexedi/rsvp.js.git
branch = master
git-executable = ${git:location}/bin/git
develop = true
[rsvp-install]
recipe = plone.recipe.command
stop-on-error = true
command = cd ${rsvp-repository.git:location} && PATH=${git:location}/bin/:${nodejs:location}/bin/:$PATH ${nodejs:location}/bin/npm install .
update_command = ${:command}
[uritemplate-repository.git]
recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/nexedi/uritemplate-js.git
branch = master
git-executable = ${git:location}/bin/git
develop = true
[uritemplate-install]
recipe = plone.recipe.command
stop-on-error = true
command = cd ${uritemplate-repository.git:location} && PATH=${git:location}/bin/:${nodejs:location}/bin/:$PATH ${nodejs:location}/bin/npm install .
update_command = ${:command}
[template-nginx-service]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/template-nginx-service.sh.in
md5sum = 529532e1240a66bdf39e3cbbef90ba87
output = ${buildout:directory}/template-nginx-service.sh.in
mode = 0644
[template-nginx-configuration]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/template-nginx.cfg.in
md5sum = 9f22db89a2679534aa8fd37dbca86782
output = ${buildout:directory}/template-nginx.cfg.in
mode = 0644
[template-runTestSuite]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/runTestSuite.in
md5sum = 515ccd82806bc2ed1bb817b75240b62e
output = ${buildout:directory}/runTestSuite.in
mode = 0644
[versions]
erp5.util = 0.4.44
slapos.recipe.template = 2.9
selenium = 2.53.1
\ No newline at end of file
#!${dash-output:dash}
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
if [ ! -e $${nginx-configuration:ssl_crt} ]
then
${openssl-output:openssl} genrsa -out $${nginx-configuration:ssl_key} 2048
${openssl-output:openssl} req -new \
-subj "/C=AA/ST=Denial/L=Nowhere/O=Dis/CN=$${nginx-configuration:ip}" \
-key $${nginx-configuration:ssl_key} -out $${nginx-configuration:ssl_csr}
${openssl-output:openssl} x509 -req -days 365 \
-in $${nginx-configuration:ssl_csr} \
-signkey $${nginx-configuration:ssl_key} \
-out $${nginx-configuration:ssl_crt}
fi
exec ${nginx-output:nginx} \
-c $${nginx-configuration:output}
\ No newline at end of file
daemon off; # run in the foreground so supervisord can look after it
worker_processes 4;
pid $${directory:run}/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
error_log $${nginx-configuration:error_log};
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
default_type application/octet-stream;
include ${nginx-output:mime};
##
# Logging Settings
##
access_log $${nginx-configuration:access_log};
error_log $${nginx-configuration:error_log};
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
server {
listen [$${nginx-configuration:ip}]:$${nginx-configuration:port};
# ssl on;
# ssl_certificate $${nginx-configuration:ssl_crt};
# ssl_certificate_key $${nginx-configuration:ssl_key};
fastcgi_temp_path $${directory:varnginx} 1 2;
uwsgi_temp_path $${directory:varnginx} 1 2;
scgi_temp_path $${directory:varnginx} 1 2;
client_body_temp_path $${directory:varnginx} 1 2;
proxy_temp_path $${directory:varnginx} 1 2;
## Only allow GET and HEAD request methods
if ($request_method !~ ^(GET|HEAD)$ ) {
return 444;
}
## Serve an error 204 (No Content) for favicon.ico
location = /favicon.ico {
return 204;
}
location /renderjs
{
alias ${renderjs-repository.git:location};
autoindex on;
disable_symlinks on;
}
location /jio
{
alias ${jio-repository.git:location};
autoindex on;
disable_symlinks on;
}
location /rsvp
{
alias ${rsvp-repository.git:location};
autoindex on;
disable_symlinks on;
}
location /uritemplate
{
alias ${uritemplate-repository.git:location};
autoindex on;
disable_symlinks on;
}
location /
{
root $${directory:www};
# autoindex on;
disable_symlinks on;
# index index.html;
}
}
}
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