Add Zope 2.12 compatibility to the testrunner

Configure the ZopeLite layer, enabling conditional product installation.

Conditionally load zcml on Zope 2.12 and delay the optimize and fortify calls
until after Product initialization by the layer.

Disable printing of profiling information on Zope 2.12 since profiling support
on ZopeTestCase has been removed.

Import copyzopeskel from its proper location on Zope 2.12 (this has a side-
effect of changing slightly the beginning of the test output, suppressing the
"Loading Zope, please stand by ..." initial message). Additionally, add a Zope
2.12 compatible skeleton.

Make sure the skin is configured on the portal object, since it's no longer
configured automatically by acquisition on CMF 2.



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@30352 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 7cdbe011
......@@ -65,6 +65,21 @@ ZopeTestCase.installProduct('MailHost', quiet=install_product_quiet)
ZopeTestCase.installProduct('PageTemplates', quiet=install_product_quiet)
ZopeTestCase.installProduct('PythonScripts', quiet=install_product_quiet)
ZopeTestCase.installProduct('ExternalMethod', quiet=install_product_quiet)
try:
from Testing.ZopeTestCase.layer import onsetup
# On Zope 2.12, installProduct() is a delayed call, so imports that depend on
# products being "initialize"d should only be called "on setup". The
# decorator above delays calls to the decorated function until after Product
# initialization.
# Also, we need Five to wire all our CMF dependencies.
ZopeTestCase.installProduct('Five', quiet=install_product_quiet)
except ImportError:
# On Zope 2.8 the call does not have to be delayed as product installation
# happens immediately
def onsetup(decorated):
return decorated
try:
# Workaround iHotFix patch that doesn't work with
# ZopeTestCase REQUESTs
......@@ -227,7 +242,7 @@ class ERP5TypeTestCase(backportUnittest.TestCase, PortalTestCase):
def shortDescription(self):
description = str(self)
doc = self._TestCase__testMethodDoc
doc = self._testMethodDoc
if doc and doc.split("\n")[0].strip():
description += ', ' + doc.split("\n")[0].strip()
return description
......@@ -269,7 +284,11 @@ class ERP5TypeTestCase(backportUnittest.TestCase, PortalTestCase):
def getPortal(self):
"""Returns the portal object, i.e. the "fixture root".
"""
return self.app[self.getPortalName()]
portal = self.app[self.getPortalName()]
# FIXME: Try not to run this call below so often by moving it somewhere
# where it is called exactly once per test.
portal.setupCurrentSkin(portal.REQUEST)
return portal
getPortalObject = getPortal
......@@ -321,7 +340,7 @@ class ERP5TypeTestCase(backportUnittest.TestCase, PortalTestCase):
self.setUp = self._decorate_setUp(self.setUp)
self.tearDown = self._decorate_tearDown(self.tearDown)
test_name = self._TestCase__testMethodName
test_name = self._testMethodName
test_method = getattr(self, test_name)
setattr(self, test_name, self._decorate_testRun(test_method))
......@@ -334,6 +353,8 @@ class ERP5TypeTestCase(backportUnittest.TestCase, PortalTestCase):
# This is a workaround for the overwriting problem in Testing/__init__.py
# in Zope. So this overwrites them again to revert the changes made by
# Testing.
# XXX: Leo: Is this still true? We need to reevaluate how we get
# information from our environment.
try:
import App.config
except ImportError:
......@@ -773,6 +794,10 @@ class ERP5TypeTestCase(backportUnittest.TestCase, PortalTestCase):
transaction.commit()
self.portal = portal
# Make sure skins are correctly set-up (it's not implicitly set up
# by Acquisition on Zope 2.12 as it is on 2.8)
portal.setupCurrentSkin(portal.REQUEST)
if len(setup_done) == 1: # make sure it is run only once
try:
from Products import DeadlockDebugger
......@@ -1086,6 +1111,7 @@ def dummy_tearDown(self):
'''
self._clear(1)
@onsetup
def optimize():
'''Significantly reduces portal creation time.'''
def __init__(self, text):
......@@ -1125,7 +1151,7 @@ def optimize():
optimize()
@onsetup
def fortify():
'''Add some extra checks that we don't have at runtime, not to slow down the
system.
......
......@@ -121,17 +121,25 @@ def initializeInstanceHome(tests_framework_home,
shutil.copy(src, dst)
else:
os.symlink(src, dst)
# add some paths where we can find copyzopeskel
sys.path.append(os.path.join(zope_home, "bin"))
sys.path.append(os.path.join(zope_home, "utilities"))
import copyzopeskel
kw = {
"PYTHON":sys.executable,
"INSTANCE_HOME": instance_home,
"SOFTWARE_HOME": software_home,
"ZOPE_HOME": zope_home,
}
skelsrc = os.path.abspath(os.path.join(os.path.dirname(__file__), "skel"))
try:
# attempt to import copyzopeskel from its new home on Zope 2.12
from Zope2.utilities import copyzopeskel
# and use the 2.12 version of our skeleton
skeldir = 'skel2.12'
kw['ZOPE_SCRIPTS'] = os.environ['ZOPE_SCRIPTS']
except ImportError:
# add some paths where we can find copyzopeskel
sys.path.append(os.path.join(zope_home, "bin"))
sys.path.append(os.path.join(zope_home, "utilities"))
import copyzopeskel
kw['ZOPE_HOME'] = zope_home
skeldir = 'skel'
skelsrc = os.path.abspath(os.path.join(os.path.dirname(__file__), skeldir))
copyzopeskel.copyskel(skelsrc, instance_home, None, None, **kw)
# site specific variables
......@@ -310,6 +318,9 @@ def runUnitTestList(test_list, verbosity=1, debug=0):
else:
products_home = os.path.join(instance_home, 'Products')
# The following un-monkey-patch is only required for Zope 2.8.
# On Zope 2.12, import_products() is called by ERP5TestCase before it is
# patched by the layer.setUp() call.
import OFS.Application
import_products = OFS.Application.import_products
from Testing import ZopeTestCase # This will import custom_zodb.py
......@@ -326,7 +337,13 @@ def runUnitTestList(test_list, verbosity=1, debug=0):
section = SectionValue({'dateformat': '%Y-%m-%d %H:%M:%S',
'format': '%(asctime)s %(levelname)s %(name)s %(message)s',
'level': logging.INFO,
'path': os.environ['EVENT_LOG_FILE']},
'path': os.environ['EVENT_LOG_FILE'],
'max_size': None,
'old_files': None,
'when': None,
'interval': None,
'formatter': None,
},
None, None)
section.handlers = [FileHandlerFactory(section)]
eventlog = EventLogFactory(section)
......@@ -336,8 +353,6 @@ def runUnitTestList(test_list, verbosity=1, debug=0):
except ImportError:
pass
TestRunner = backportUnittest.TextTestRunner
# allow unit tests of our Products or business templates to be reached.
from glob import glob
product_test_list = glob(os.path.join(products_home, '*', 'tests'))
......@@ -366,6 +381,9 @@ def runUnitTestList(test_list, verbosity=1, debug=0):
save = int(os.environ.get('erp5_save_data_fs', 0))
dummy_test = save and (int(os.environ.get('update_business_templates', 0))
or not int(os.environ.get('erp5_load_data_fs', 0)))
TestRunner = backportUnittest.TextTestRunner
if dummy_test:
# Skip all tests in save mode and monkeypatch PortalTestCase.setUp
# to skip beforeSetUp and afterSetUp. Also patch unittest.makeSuite,
......@@ -382,7 +400,7 @@ def runUnitTestList(test_list, verbosity=1, debug=0):
# Hack the profiler to run only specified test methods, and wrap results when
# running in debug mode.
if debug:
class DebugTextTestRunner(backportUnittest.TextTestRunner):
class DebugTextTestRunner(TestRunner):
def _makeResult(self):
result = super(DebugTextTestRunner, self)._makeResult()
return DebugTestResult(result)
......@@ -396,6 +414,18 @@ def runUnitTestList(test_list, verbosity=1, debug=0):
# change current directory to the test home, to create zLOG.log in this dir.
os.chdir(tests_home)
try:
from Testing.ZopeTestCase import layer
except ImportError:
# Zope 2.8, no need to set-up the ZopeLite layer
pass
else:
# Since we're not using the zope.testing testrunner, we need to set up
# the layer ourselves
# FIXME: We should start using Zope layers. Our setup will probably
# be faster and we could drop most of this code we currently maintain
# ourselves
layer.ZopeLite.setUp()
result = TestRunner(verbosity=verbosity).run(suite)
if save:
......@@ -508,8 +538,13 @@ def main():
result = runUnitTestList(test_list=test_list,
verbosity=verbosity,
debug=debug)
from Testing.ZopeTestCase import profiler
profiler.print_stats()
try:
from Testing.ZopeTestCase import profiler
except ImportError:
if os.environ.get('PROFILE_TESTS') == '1':
print "Profiler support is not available from ZopeTestCase in Zope 2.12"
else:
profiler.print_stats()
sys.exit(len(result.failures) + len(result.errors))
if __name__ == '__main__':
......
@set INSTANCE_HOME=<<INSTANCE_HOME>>
@set CONFIG_FILE=%INSTANCE_HOME%\etc\zope.conf
@set ZOPE_RUN=<<ZOPE_SCRIPTS>>\runzope
@set erp5_load_data_fs=1
"%ZOPE_RUN%" -C "%CONFIG_FILE%" %1 %2 %3 %4 %5 %6 %7
#! /bin/sh
INSTANCE_HOME="<<INSTANCE_HOME>>"
CONFIG_FILE="<<INSTANCE_HOME>>/etc/zope.conf"
ZOPE_RUN="<<ZOPE_SCRIPTS>>/runzope"
export INSTANCE_HOME
export erp5_load_data_fs="1"
exec "$ZOPE_RUN" -C "$CONFIG_FILE" "$@"
@set PYTHON=<<PYTHON>>
@set INSTANCE_HOME=<<INSTANCE_HOME>>
@set CONFIG_FILE=%INSTANCE_HOME%\etc\zope.conf
@set ZDCTL=<<ZOPE_SCRIPTS>>\zopectl
@set export erp5_load_data_fs="1"
"%ZDCTL%" -C "%CONFIG_FILE%" %1 %2 %3 %4 %5 %6 %7
#! /bin/sh
PYTHON="<<PYTHON>>"
INSTANCE_HOME="<<INSTANCE_HOME>>"
CONFIG_FILE="<<INSTANCE_HOME>>/etc/zope.conf"
ZDCTL="<<ZOPE_SCRIPTS>>/zopectl"
export INSTANCE_HOME
export PYTHON
export erp5_load_data_fs="1"
exec "$ZDCTL" -C "$CONFIG_FILE" "$@"
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:meta="http://namespaces.zope.org/meta"
xmlns:five="http://namespaces.zope.org/five">
<include package="Products.Five" />
<meta:redefinePermission from="zope2.Public" to="zope.Public" />
<!-- Load the meta -->
<include files="package-includes/*-meta.zcml" />
<five:loadProducts file="meta.zcml"/>
<!-- Load the configuration -->
<include files="package-includes/*-configure.zcml" />
<five:loadProducts />
<!-- Load the configuration overrides-->
<includeOverrides files="package-includes/*-overrides.zcml" />
<five:loadProductsOverrides />
<securityPolicy
component="Products.Five.security.FiveSecurityPolicy" />
</configure>
This diff is collapsed.
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