Commit 54683e0c authored by Jérome Perrin's avatar Jérome Perrin

new --processing_node_loop=timerserver argument for runUnitTest

and several small fixes or changes to make this easier

See merge request !1642
parents 123635b9 61e8a9ce
......@@ -26,7 +26,6 @@ from cPickle import dumps
from glob import glob
from hashlib import md5
from warnings import warn
from ExtensionClass import pmc_init_of
from DateTime import DateTime
import Products.ZMySQLDA.DA
from Products.ZMySQLDA.DA import Connection as ZMySQLDA_Connection
......@@ -65,7 +64,7 @@ from zLOG import LOG, DEBUG
from Products.ERP5Type.Utils import convertToUpperCase
from Products.ERP5Type.tests.backportUnittest import SetupSiteError
from Products.ERP5Type.tests.utils import addUserToDeveloperRole
from Products.ERP5Type.tests.utils import DummyMailHostMixin, parseListeningAddress
from Products.ERP5Type.tests.utils import parseListeningAddress
# Quiet messages when installing business templates
install_bt5_quiet = 0
......@@ -354,23 +353,6 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase):
if not uf.getUserById(user_name):
uf._doAddUser(user_name, self.newPassword(), ['Member'], [])
def _setUpDummyMailHost(self):
"""Replace Original Mail Host by Dummy Mail Host in a non-persistent way
"""
cls = self.portal.MailHost.__class__
if not issubclass(cls, DummyMailHostMixin):
cls.__bases__ = (DummyMailHostMixin,) + cls.__bases__
pmc_init_of(cls)
def _restoreMailHost(self):
"""Restore original Mail Host
"""
if self.portal is not None:
cls = self.portal.MailHost.__class__
if cls.__bases__[0] is DummyMailHostMixin:
cls.__bases__ = cls.__bases__[1:]
pmc_init_of(cls)
def pinDateTime(self, date_time):
# pretend time has stopped at a certain date (i.e. the test runs
# infinitely fast), for example to avoid errors on tests that are started
......@@ -1593,7 +1575,7 @@ class ZEOServerTestCase(ERP5TypeTestCase):
pass
def tearDown(self):
self.zeo_server.close_server()
self.zeo_server.close()
class lazy_func_prop(object):
......
......@@ -9,8 +9,9 @@ from Testing import ZopeTestCase
from ZODB.POSException import ConflictError
from zLOG import LOG, ERROR
from Products.CMFActivity.Activity.Queue import VALIDATION_ERROR_DELAY
from ExtensionClass import pmc_init_of
from Products.ERP5Type.tests.utils import \
addUserToDeveloperRole, createZServer, parseListeningAddress
addUserToDeveloperRole, createZServer, DummyMailHostMixin, parseListeningAddress
from Products.CMFActivity.ActivityTool import getCurrentNode
......@@ -334,7 +335,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
This aborts current transaction.
"""
for i in xrange(30):
for i in xrange(60):
node_list = list(self.portal.portal_activities.getProcessingNodeList())
if len(node_list) >= node_count:
node_list.remove(getCurrentNode())
......@@ -354,6 +355,23 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
self._registerNode(distributing=not cluster, processing=1)
self.commit()
def _setUpDummyMailHost(self):
"""Replace Original Mail Host by Dummy Mail Host in a non-persistent way
"""
cls = self.portal.MailHost.__class__
if not issubclass(cls, DummyMailHostMixin):
cls.__bases__ = (DummyMailHostMixin,) + cls.__bases__
pmc_init_of(cls)
def _restoreMailHost(self):
"""Restore original Mail Host
"""
if self.portal is not None:
cls = self.portal.MailHost.__class__
if cls.__bases__[0] is DummyMailHostMixin:
cls.__bases__ = cls.__bases__[1:]
pmc_init_of(cls)
def processing_node(self):
"""Main loop for nodes that process activities"""
try:
......@@ -361,9 +379,10 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
time.sleep(.3)
transaction.begin()
try:
portal = self.app[self.app.test_portal_name]
portal = self.portal = self.app[self.app.test_portal_name]
except (AttributeError, KeyError):
continue
self._setUpDummyMailHost()
if portal.portal_activities.isSubscribed():
try:
portal.portal_activities.process_timer(None, None)
......@@ -371,3 +390,26 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
LOG('Invoking Activity Tool', ERROR, '', error=True)
except KeyboardInterrupt:
pass
def timerserver(self):
"""Main loop using timer server.
"""
import Products.TimerService
timerserver_thread = None
try:
while not Lifetime._shutdown_phase:
time.sleep(.3)
transaction.begin()
try:
self.portal = self.app[self.app.test_portal_name]
except (AttributeError, KeyError):
continue
self._setUpDummyMailHost()
if not timerserver_thread:
timerserver_thread = Products.TimerService.timerserver.TimerServer.TimerServer(
module='Zope2',
interval=0.1,
)
except KeyboardInterrupt:
pass
......@@ -141,8 +141,18 @@ 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.
--processing_node_loop=LOOP
Make ZEO clients execute the given loop, one of:
- processing_node: process activities only.
this is the default.
- timerserver: start a timer server thread,
which will typically execute activities,
alarms and everything else registered on
timer service.
This option only makes sense with --activity_node=
or when not specifying a test to run.
--zserver=ADDRESS[,...] Make ZServer listen on given IPv4 address.
Adresses can be given in the following syntaxs:
Addresses 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
......@@ -492,7 +502,7 @@ _print = sys.stderr.write
def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
if "zeo_client" in os.environ and "zeo_server" in os.environ:
_print("conflicting options: --zeo_client and --zeo_server")
_print("conflicting options: --zeo_client and --zeo_server\n")
sys.exit(1)
instance_home = os.environ['INSTANCE_HOME']
os.environ.setdefault('EVENT_LOG_FILE', os.path.join(log_directory, 'zLOG.log'))
......@@ -547,8 +557,11 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
# On recent Zope, ZopeTestCase does not have any logging facility.
# So we must emulate the usual Zope startup code to catch log messages.
from ZConfig.matcher import SectionValue
logging_format = '%(asctime)s.%(msecs)03d %(levelname)s %(name)s %(message)s'
if os.environ.get('activity_node'):
logging_format = '%(process)d ' + logging_format
section = SectionValue({'dateformat': '%Y-%m-%d %H:%M:%S',
'format': '%(asctime)s.%(msecs)03d %(levelname)s %(name)s %(message)s',
'format': logging_format,
'level': logging.INFO,
'path': os.environ['EVENT_LOG_FILE'],
'max_size': None,
......@@ -638,11 +651,12 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
if zeo_server_pid == 0:
suite = ZEOServerTestCase('asyncore_loop')
elif node_pid_list is None or not test_list:
suite = ProcessingNodeTestCase('processing_node')
processing_node_loop = os.environ.get('processing_node_loop', 'processing_node')
suite = ProcessingNodeTestCase(processing_node_loop)
if not (dummy or load):
_print('WARNING: either --save or --load should be used because static'
' files are only reloaded by the node installing business'
' templates.')
' templates.\n')
else:
if dummy:
# Skip all tests and monkeypatch PortalTestCase to skip
......@@ -668,7 +682,7 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
ERP5TypeTestLoader.filter_test_list = None
if node_pid_list is None:
result = suite()
result = suite.debug()
else:
if not test_list:
root_logger.handlers.append(loghandler.StreamHandler(sys.stderr))
......@@ -763,6 +777,7 @@ def main(argument_list=None):
"live_instance=",
"zeo_client=",
"zeo_server=",
"processing_node_loop=",
"zserver=",
"zserver_frontend_url=",
"neo_storage",
......@@ -878,6 +893,8 @@ def main(argument_list=None):
os.environ["zeo_client"] = arg
elif opt == "--zeo_server":
os.environ["zeo_server"] = arg
elif opt == "--processing_node_loop":
os.environ["processing_node_loop"] = arg
elif opt == "--zserver":
os.environ["zserver"] = arg
elif opt == "--zserver_frontend_url":
......
......@@ -65,7 +65,7 @@ class TimerServer(threading.Thread):
_module_name=module_name,
_request=request,
_response=response)
server.add_task(self)
server.task_dispatcher.add_task(self)
def cancel(self):
pass
......
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