Commit 0a09fe10 authored by Jérome Perrin's avatar Jérome Perrin

test: start test runner's zserver on partition IP and access it through an apache https proxy

Extend test runners to use partition IP  and run functional tests behind an https frontend.

See nexedi/slapos!374 for the slapos part and more detailed explanations.

/reviewed-on nexedi/erp5!729
parents 2a2ee5d3 31d4adde
......@@ -172,19 +172,30 @@ class FunctionalTestRunner:
return self.portal.portal_tests.TestTool_getResults(self.run_only)
def _getTestURL(self):
return ZELENIUM_BASE_URL % (self.portal.portal_url(), self.run_only,
self.user, self.password)
# Access the https proxy in front of runUnitTest's zserver
base_url = os.getenv('zserver_frontend_url')
if base_url:
base_url = '%s%s' % (base_url, self.portal.getId())
else:
base_url = self.portal.portal_url()
return ZELENIUM_BASE_URL % (
base_url,
self.run_only,
self.user,
self.password)
def test(self, debug=0):
xvfb = Xvfb(self.instance_home)
try:
if not debug:
if not (debug and os.getenv('DISPLAY')):
print("\nSet 'erp5_debug_mode' environment variable to 1"
" to use your existing display instead of Xvfb.")
xvfb.run()
capabilities = webdriver.common.desired_capabilities \
.DesiredCapabilities.FIREFOX.copy()
capabilities['marionette'] = True
# Zope is accessed through apache with a certificate not trusted by firefox
capabilities['acceptInsecureCerts'] = True
# Service workers are disabled on Firefox 52 ESR:
# https://bugzilla.mozilla.org/show_bug.cgi?id=1338144
options = webdriver.FirefoxOptions()
......
......@@ -24,6 +24,10 @@ class ERP5TypeTestSuite(TestSuite):
if self.__dict__.has_key("bt5_path"):
args = ("--bt5_path=%s" % self.bt5_path,) + args
instance_number = self.instance or 1
args = (
'--zserver=%s' % self.zserver_address_list[instance_number-1],
'--zserver_frontend_url=%s' % self.zserver_frontend_url_list[instance_number-1],
) + args
mysql_db_list = self.mysql_db_list[
(instance_number-1) * self.mysql_db_count:
(instance_number) * self.mysql_db_count]
......
......@@ -154,7 +154,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
try:
_print(createZServer(log, zserver_type='webdav'))
except RuntimeError, e:
ZopeTestCase._print(str(e))
ZopeTestCase._print('Could not start webdav zserver: %s\n' % e)
t = Thread(target=Lifetime.loop)
t.setDaemon(1)
t.start()
......
#!/usr/bin/env python2.7
import argparse, sys
import argparse, sys, os, textwrap
from erp5.util import taskdistribution
# XXX: This import is required, just to populate sys.modules['test_suite'].
......@@ -10,8 +10,14 @@ def _parsingErrorHandler(data, _):
print >> sys.stderr, 'Error parsing data:', repr(data)
taskdistribution.patchRPCParser(_parsingErrorHandler)
def makeSuite(node_quantity=None, test_suite=None, revision=None,
db_list=None, **kwargs):
def makeSuite(
node_quantity=None,
test_suite=None,
revision=None,
db_list=None,
zserver_address_list=None,
zserver_frontend_url_list=None,
**kwargs):
# BBB tests (plural form) is only checked for backward compatibility
for k in sys.modules.keys():
if k in ('tests', 'test',) or k.startswith('tests.') or k.startswith('test.'):
......@@ -32,38 +38,71 @@ def makeSuite(node_quantity=None, test_suite=None, revision=None,
suite = suite_class(revision=revision,
max_instance_count=node_quantity,
mysql_db_list=db_list.split(','),
zserver_address_list=zserver_address_list.split(','),
zserver_frontend_url_list=zserver_frontend_url_list.split(','),
**kwargs)
return suite
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 = argparse.ArgumentParser(
description='Run a test suite.',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''
Tips:
Running a full test suite on a development machine can be achieved with:
%(prog)s --node_quantity=3 --test_suite=ERP5 --xvfb_bin=/path/to/Xvfb --firefox_bin=/path/to/firefox
'''))
# Parameters included in wrappers generated by SlapOS ERP5 software release.
# To handle backward compatibity, we prefer that the generated wrapper pass
# these parameters as environment variables. This way, if SlapOS SR is more
# recent, the parameter will be ignored by ERP5.
slapos_wrapper_group = parser.add_argument_group(
'SlapOS wrapper arguments',
description='Arguments passed automatically by SlapOS generated wrapper')
slapos_wrapper_group.add_argument('--db_list', help='A list of comma separated sql connection strings')
slapos_wrapper_group.add_argument('--conversion_server_url', default=None)
slapos_wrapper_group.add_argument('--conversion_server_retry_count', default=None)
slapos_wrapper_group.add_argument('--conversion_server_hostname', default=None)
slapos_wrapper_group.add_argument('--conversion_server_port', default=None)
slapos_wrapper_group.add_argument('--volatile_memcached_server_hostname', default=None)
slapos_wrapper_group.add_argument('--volatile_memcached_server_port', default=None)
slapos_wrapper_group.add_argument('--persistent_memcached_server_hostname', default=None)
slapos_wrapper_group.add_argument('--persistent_memcached_server_port', default=None)
slapos_wrapper_group.add_argument('--bt5_path', default=None)
slapos_wrapper_group.add_argument(
'--zserver_address_list',
help='A list of comma seperated host:port for ZServer.\n'
'Also taken from zserver_address_list environment variable.',
default=os.getenv('zserver_address_list'))
slapos_wrapper_group.add_argument(
'--zserver_frontend_url_list',
help='A list of comma seperated frontend URLs, one for each of zserver_address_list,'
'in the same order.\nAlso taken from zserver_frontend_url_list environment variable',
default=os.getenv('zserver_frontend_url_list'))
# Parameters passed by test node
testnode_group = parser.add_argument_group(
'test node arguments',
description='Arguments passed by testnode')
testnode_group.add_argument('--test_suite', help='The test suite name')
testnode_group.add_argument('--test_suite_title', help='The test suite title',
default=None)
parser.add_argument('--test_node_title', help='The test node title',
testnode_group.add_argument('--test_node_title', help='The test node title',
default=None)
parser.add_argument('--project_title', help='The project title',
testnode_group.add_argument('--project_title', help='The project title',
default=None)
parser.add_argument('--revision', help='The revision to test',
testnode_group.add_argument('--revision', help='The revision to test',
default='dummy_revision')
parser.add_argument('--node_quantity', help='Number of parallel tests to run',
testnode_group.add_argument('--node_quantity', help='Number of parallel tests to run',
default=1, type=int)
parser.add_argument('--master_url',
testnode_group.add_argument('--master_url',
help='The Url of Master controling many suites',
default=None)
parser.add_argument('--db_list', help='A list of sql connection strings')
# parameters that needs to be passed to runUnitTest
parser.add_argument('--conversion_server_url', default=None)
parser.add_argument('--conversion_server_retry_count', default=None)
parser.add_argument('--conversion_server_hostname', default=None)
parser.add_argument('--conversion_server_port', default=None)
parser.add_argument('--volatile_memcached_server_hostname', default=None)
parser.add_argument('--volatile_memcached_server_port', default=None)
parser.add_argument('--persistent_memcached_server_hostname', default=None)
parser.add_argument('--persistent_memcached_server_port', default=None)
parser.add_argument('--bt5_path', default=None)
parser.add_argument("--xvfb_bin", default=None)
parser.add_argument("--firefox_bin", default=None)
testnode_group.add_argument("--xvfb_bin", default=None)
testnode_group.add_argument("--firefox_bin", default=None)
args = parser.parse_args()
if args.bt5_path is not None:
......@@ -71,10 +110,21 @@ def main():
master = taskdistribution.TaskDistributor(args.master_url)
test_suite_title = args.test_suite_title or args.test_suite
revision = args.revision
if len(args.zserver_address_list.split(",")) < args.node_quantity:
print >> sys.stderr, 'Not enough zserver address/frontends for node quantity %s (%r)' % (
args.node_quantity, args.zserver_address_list)
sys.exit(1)
# sanity check
assert len(args.zserver_address_list.split(",")) == len(args.zserver_frontend_url_list.split(","))
suite = makeSuite(test_suite=args.test_suite,
node_quantity=args.node_quantity,
revision=revision,
db_list=args.db_list,
zserver_address_list=args.zserver_address_list,
zserver_frontend_url_list=args.zserver_frontend_url_list,
bt5_path=args.bt5_path,
firefox_bin=args.firefox_bin,
xvfb_bin=args.xvfb_bin)
......
......@@ -141,10 +141,17 @@ Options:
activities.
--zeo_server=[[HOST:]PORT] Bind the ZEO server to the given host/port.
--zeo_client=[HOST:]PORT Use specified ZEO server as storage.
--zserver=[HOST:]PORT[,...]
Make ZServer listen on given host:port
--zserver=ADDRESS[,...] Make ZServer listen on given IPv4 address.
Adresses can be given in the following syntaxs:
- HOST:PORT
- PORT in this case, host will be 127.0.0.1
- HOST in this case a free port will be assigned
If used with --activity_node=, this can be a
comma-separated list of addresses.
--zserver_frontend_url=STRING
URL of an http proxy where the zserver is reachable.
When running zelenium tests, the zserver will be
accessed from this URL.
--neo_storage Use a NEO storage (SQLite) instead of FileStorage.
--products_path=path,path Comma-separated list of products paths locations
which shall be used in test environment.
......@@ -727,6 +734,7 @@ def main(argument_list=None):
"zeo_client=",
"zeo_server=",
"zserver=",
"zserver_frontend_url=",
"neo_storage",
"products_path=",
"sys_path=",
......@@ -839,6 +847,8 @@ def main(argument_list=None):
os.environ["zeo_server"] = arg
elif opt == "--zserver":
os.environ["zserver"] = arg
elif opt == "--zserver_frontend_url":
os.environ["zserver_frontend_url"] = arg
elif opt == "--neo_storage":
os.environ["neo_storage"] = ""
elif opt == "--products_path":
......
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