[Erp5-report] r42528 seb - /erp5/trunk/products/ERP5Type/tests/
nobody at svn.erp5.org
nobody at svn.erp5.org
Thu Jan 20 19:13:36 CET 2011
Author: seb
Date: Thu Jan 20 19:13:35 2011
New Revision: 42528
URL: http://svn.erp5.org?rev=42528&view=rev
Log:
create mixin class for code common between live tests
and command line tests
Modified:
erp5/trunk/products/ERP5Type/tests/ERP5TypeLiveTestCase.py
erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py
Modified: erp5/trunk/products/ERP5Type/tests/ERP5TypeLiveTestCase.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/tests/ERP5TypeLiveTestCase.py?rev=42528&r1=42527&r2=42528&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/tests/ERP5TypeLiveTestCase.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/tests/ERP5TypeLiveTestCase.py [utf8] Thu Jan 20 19:13:35 2011
@@ -35,6 +35,7 @@ from Testing.ZopeTestCase import PortalT
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.tests.ProcessingNodeTestCase import ProcessingNodeTestCase
from Products.ERP5Type.Globals import get_request
+from ERP5TypeTestCase import ERP5TypeTestCaseMixin
import transaction
from zLOG import LOG, DEBUG, INFO
@@ -58,7 +59,7 @@ from Products.ERP5Type.tests import Proc
ProcessingNodeTestCaseModule
ProcessingNodeTestCaseModule.patchActivityTool = lambda: None
-class ERP5TypeLiveTestCase(ProcessingNodeTestCase, PortalTestCase):
+class ERP5TypeLiveTestCase(ERP5TypeTestMixin):
"""ERP5TypeLiveTestCase is the default class for *all* tests
in ERP5. It is designed with the idea in mind that tests should
be run through the web. Command line based tests may be helpful
@@ -73,18 +74,6 @@ class ERP5TypeLiveTestCase(ProcessingNod
defined.
"""
- def shortDescription(self):
- description = str(self)
- doc = self._testMethodDoc
- if doc and doc.split("\n")[0].strip():
- description += ', ' + doc.split("\n")[0].strip()
- return description
-
- def getTitle(self):
- """Returns the title of the test, for test reports.
- """
- return str(self.__class__)
-
def getPortalName(self):
""" Return the default ERP5 site id.
"""
@@ -102,47 +91,18 @@ class ERP5TypeLiveTestCase(ProcessingNod
getPortalObject = getPortal
- def login(self, user_name='ERP5TypeTestCase', quiet=0):
- """
- Most of the time, we need to login before doing anything
- """
- PortalTestCase.login(self, user_name)
-
- def logout(self):
- PortalTestCase.logout(self)
- # clean up certain cache related REQUEST keys that might be associated
- # with the logged in user
- for key in ('_ec_cache', '_oai_cache'):
- pass
- #self.REQUEST.other.pop(key, None) # XXX
+ #def logout(self):
+ # PortalTestCase.logout(self)
+ # # clean up certain cache related REQUEST keys that might be associated
+ # # with the logged in user
+ # for key in ('_ec_cache', '_oai_cache'):
+ # pass
+ # #self.REQUEST.other.pop(key, None) # XXX
def _close(self):
'''Closes the ZODB connection.'''
transaction.abort()
- # class-defined decorators for profiling.
- # Depending on the environment variable, they return
- # the same method, or a profiling wrapped call
- _decorate_setUp = profile_if_environ('PROFILE_SETUP')
- _decorate_testRun = profile_if_environ('PROFILE_TESTS')
- _decorate_tearDown = profile_if_environ('PROFILE_TEARDOWN')
-
- def __call__(self, *args, **kw):
- # Pulling down the profiling from ZopeTestCase.profiler to allow
- # overriding run()
- # This cannot be done at instanciation because we need to
- # wrap the bottom-most methods, e.g.
- # SecurityTestCase.tearDown instead of ERP5TestCase.tearDown
-
- self.setUp = self._decorate_setUp(self.setUp)
- self.tearDown = self._decorate_tearDown(self.tearDown)
-
- test_name = self._testMethodName
- test_method = getattr(self, test_name)
- setattr(self, test_name, self._decorate_testRun(test_method))
-
- self.run(*args, **kw)
-
def _setup(self):
'''Configures the portal. Framework authors may
override.
@@ -188,171 +148,6 @@ class ERP5TypeLiveTestCase(ProcessingNod
'''
pass
- def logMessage(self, message):
- """
- Shortcut function to log a message
- """
- ZopeTestCase._print('\n%s ' % message)
- LOG('Testing ... ', DEBUG, message)
-
- # Utility methods specific to ERP5Type
- def getTemplateTool(self):
- return getToolByName(self.getPortal(), 'portal_templates', None)
-
- def getPreferenceTool(self) :
- return getToolByName(self.getPortal(), 'portal_preferences', None)
-
- def getTrashTool(self):
- return getToolByName(self.getPortal(), 'portal_trash', None)
-
- def getPasswordTool(self):
- return getToolByName(self.getPortal(), 'portal_password', None)
-
- def getSkinsTool(self):
- return getToolByName(self.getPortal(), 'portal_skins', None)
-
- def getCategoryTool(self):
- return getToolByName(self.getPortal(), 'portal_categories', None)
-
- def getWorkflowTool(self):
- return getToolByName(self.getPortal(), 'portal_workflow', None)
-
- def getCatalogTool(self):
- return getToolByName(self.getPortal(), 'portal_catalog', None)
-
- def getTypesTool(self):
- return getToolByName(self.getPortal(), 'portal_types', None)
- getTypeTool = getTypesTool
-
- def getRuleTool(self):
- return getattr(self.getPortal(), 'portal_rules', None)
-
- def getClassTool(self):
- return getattr(self.getPortal(), 'portal_classes', None)
-
- def getSimulationTool(self):
- return getToolByName(self.getPortal(), 'portal_simulation', None)
-
- def getSQLConnection(self):
- return getToolByName(self.getPortal(), 'erp5_sql_connection', None)
-
- def getPortalId(self):
- return self.getPortal().getId()
-
- def getDomainTool(self):
- return getToolByName(self.getPortal(), 'portal_domains', None)
-
- def getAlarmTool(self):
- return getattr(self.getPortal(), 'portal_alarms', None)
-
- def getActivityTool(self):
- return getattr(self.getPortal(), 'portal_activities', None)
-
- def getArchiveTool(self):
- return getattr(self.getPortal(), 'portal_archives', None)
-
- def getCacheTool(self):
- return getattr(self.getPortal(), 'portal_caches', None)
-
- def getOrganisationModule(self):
- return getattr(self.getPortal(), 'organisation_module',
- getattr(self.getPortal(), 'organisation', None))
-
- def getPersonModule(self):
- return getattr(self.getPortal(), 'person_module',
- getattr(self.getPortal(), 'person', None))
-
- def getCurrencyModule(self):
- return getattr(self.getPortal(), 'currency_module',
- getattr(self.getPortal(), 'currency', None))
-
- def validateRules(self):
- """
- try to validate all rules in rule_tool.
- """
- rule_tool = self.getRuleTool()
- for rule in rule_tool.contentValues(
- portal_type=rule_tool.getPortalRuleTypeList()):
- if rule.getValidationState() != 'validated':
- rule.validate()
-
- def createSimpleUser(self, title, reference, function):
- """
- Helper function to create a Simple ERP5 User.
- User password is the reference.
-
- XXX-JPS do wa have a "delete" method etc.
- """
- user = self.createUser(reference, person_kw=dict(title=title))
- assignment = self.createUserAssignement(user, assignment_kw=dict(function=function))
- return user
-
- def createUser(self, reference, password=None, person_kw=None):
- """
- Create an ERP5 User.
- Default password is the reference.
- person_kw is passed as additional arguments when creating the person
- """
- if password is None:
- password = reference
- if person_kw is None:
- person_kw = dict()
-
- person = self.portal.person_module.newContent(portal_type='Person',
- reference=reference,
- password=password,
- **person_kw)
- return person
-
- def createUserAssignment(self, user, assignment_kw):
- """
- Create an assignment to user.
- """
- assignment = user.newContent(portal_type='Assignment', **assignment_kw)
- assignment.open()
- return assignment
-
- def createUserAssignement(self, user, assignment_kw):
- # BBB
- warn('createUserAssignement is deprecated;'
- 'Use createUserAssignment instead',
- DeprecationWarning)
- return self.createUserAssignment(user, assignment_kw)
-
- def failIfDifferentSet(self, a, b, msg=""):
- if not msg:
- msg='%r != %r' % (a, b)
- for i in a:
- self.failUnless(i in b, msg)
- for i in b:
- self.failUnless(i in a, msg)
- self.assertEquals(len(a), len(b), msg)
- assertSameSet = failIfDifferentSet
-
- def assertWorkflowTransitionFails(self, object, workflow_id, transition_id,
- error_message=None, state_variable='simulation_state'):
- """
- Check that passing given transition from given workflow on given object
- raises ValidationFailed.
- Do sanity checks (workflow history length increased by one, simulation
- state unchanged).
- If error_message is provided, it is asserted to be equal to the last
- workflow history error message.
- """
- workflow_tool = self.getWorkflowTool()
- reference_history_length = len(workflow_tool.getInfoFor(ob=object, name='history', wf_id=workflow_id))
- state_method = 'get' + convertToUpperCase(state_variable)
- method = getattr(object, state_method, None)
- reference_workflow_state = method()
- self.assertRaises(ValidationFailed, workflow_tool.doActionFor, object, transition_id, wf_id=workflow_id)
- workflow_history = workflow_tool.getInfoFor(ob=object, name='history', wf_id=workflow_id)
- self.assertEqual(len(workflow_history), reference_history_length + 1)
- workflow_error_message = str(workflow_history[-1]['error_message'])
- if error_message is not None:
- self.assertEqual(workflow_error_message, error_message)
- self.assertEqual(method(), reference_workflow_state)
- return workflow_error_message
-
def tearDown(self):
'''Tears down the fixture. Do not override,
use the hooks instead.
@@ -365,85 +160,6 @@ class ERP5TypeLiveTestCase(ProcessingNod
"""
PortalTestCase.beforeClose(self)
- def stepPdb(self, sequence=None, sequence_list=None):
- """Invoke debugger"""
- try: # try ipython if available
- import IPython
- IPython.Shell.IPShell(argv=[])
- tracer = IPython.Debugger.Tracer()
- except ImportError:
- from pdb import set_trace as tracer
- tracer()
-
- def stepTic(self, **kw):
- """
- The is used to simulate the zope_tic_loop script
- Each time this method is called, it simulates a call to tic
- which invoke activities in the Activity Tool
- """
- if kw.get('sequence', None) is None:
- # in case of using not in sequence commit transaction
- transaction.commit()
- self.tic()
-
- def publish(self, path, basic=None, env=None, extra=None,
- request_method='GET', stdin=None, handle_errors=True):
- '''Publishes the object at 'path' returning a response object.'''
-
- from ZPublisher.Response import Response
- from ZPublisher.Test import publish_module
-
- from AccessControl.SecurityManagement import getSecurityManager
- from AccessControl.SecurityManagement import setSecurityManager
-
- # Save current security manager
- sm = getSecurityManager()
-
- # Commit the sandbox for good measure
- transaction.commit()
-
- if env is None:
- env = {}
- if extra is None:
- extra = {}
-
- request = self.app.REQUEST
-
- env['SERVER_NAME'] = request['SERVER_NAME']
- env['SERVER_PORT'] = request['SERVER_PORT']
- env['HTTP_ACCEPT_CHARSET'] = request['HTTP_ACCEPT_CHARSET']
- env['REQUEST_METHOD'] = request_method
-
- p = path.split('?')
- if len(p) == 1:
- env['PATH_INFO'] = p[0]
- elif len(p) == 2:
- [env['PATH_INFO'], env['QUERY_STRING']] = p
- else:
- raise TypeError, ''
-
- if basic:
- env['HTTP_AUTHORIZATION'] = "Basic %s" % base64.encodestring(basic).replace('\012', '')
-
- if stdin is None:
- stdin = StringIO()
-
- outstream = StringIO()
- response = Response(stdout=outstream, stderr=sys.stderr)
-
- publish_module('Zope2',
- response=response,
- stdin=stdin,
- environ=env,
- extra=extra,
- debug=not handle_errors,
- )
-
- # Restore security manager
- setSecurityManager(sm)
-
- return ResponseWrapper(response, outstream, path)
-
def runLiveTest(test_list, verbosity=1, stream=None, **kw):
from Products.ERP5Type.tests.runUnitTest import DebugTestResult
from Products.ERP5Type.tests.runUnitTest import ERP5TypeTestLoader
Modified: erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py?rev=42528&r1=42527&r2=42528&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/tests/ERP5TypeTestCase.py [utf8] Thu Jan 20 19:13:35 2011
@@ -274,10 +274,8 @@ def profile_if_environ(environment_var_n
# No profiling, return identity decorator
return lambda self, method: method
-class ERP5TypeTestCase(ProcessingNodeTestCase, PortalTestCase):
- """TestCase for ERP5 based tests.
-
- This TestCase setups an ERP5Site and installs business templates.
+class ERP5TypeTestMixin(ProcessingNodeTestCase, PortalTestCase):
+ """Mixin class for ERP5 based tests.
"""
def shortDescription(self):
@@ -287,10 +285,6 @@ class ERP5TypeTestCase(ProcessingNodeTes
description += ', ' + doc.split("\n")[0].strip()
return description
- def dummy_test(self):
- ZopeTestCase._print('All tests are skipped when --save option is passed '
- 'with --update_business_templates or without --load')
-
def getRevision(self):
erp5_path = os.path.join(instancehome, 'Products', 'ERP5')
try:
@@ -304,6 +298,340 @@ class ERP5TypeTestCase(ProcessingNodeTes
"""
return str(self.__class__)
+ def login(self, user_name='ERP5TypeTestCase', quiet=0):
+ """
+ Most of the time, we need to login before doing anything
+ """
+ PortalTestCase.login(self, user_name)
+
+ def logout(self):
+ PortalTestCase.logout(self)
+ # clean up certain cache related REQUEST keys that might be associated
+ # with the logged in user
+ for key in ('_ec_cache', '_oai_cache'):
+ self.REQUEST.other.pop(key, None)
+
+ def _setupUser(self):
+ '''Creates the default user.'''
+ uf = self.portal.acl_users
+ # do nothing if the user already exists
+ if not uf.getUser(user_name):
+ uf._doAddUser(user_name, 'secret', ['Member'], [])
+
+ def getDefaultSitePreferenceId(self):
+ """Default id, usefull method to override
+ """
+ return "default_site_preference"
+
+ # Utility methods specific to ERP5Type
+ def getTemplateTool(self):
+ return getToolByName(self.getPortal(), 'portal_templates', None)
+
+ def getPreferenceTool(self) :
+ return getToolByName(self.getPortal(), 'portal_preferences', None)
+
+ def getTrashTool(self):
+ return getToolByName(self.getPortal(), 'portal_trash', None)
+
+ def getPasswordTool(self):
+ return getToolByName(self.getPortal(), 'portal_password', None)
+
+ def getSkinsTool(self):
+ return getToolByName(self.getPortal(), 'portal_skins', None)
+
+ def getCategoryTool(self):
+ return getToolByName(self.getPortal(), 'portal_categories', None)
+
+ def getWorkflowTool(self):
+ return getToolByName(self.getPortal(), 'portal_workflow', None)
+
+ def getCatalogTool(self):
+ return getToolByName(self.getPortal(), 'portal_catalog', None)
+
+ def getTypesTool(self):
+ return getToolByName(self.getPortal(), 'portal_types', None)
+ getTypeTool = getTypesTool
+
+ def getRuleTool(self):
+ return getattr(self.getPortal(), 'portal_rules', None)
+
+ def getClassTool(self):
+ return getattr(self.getPortal(), 'portal_classes', None)
+
+ def getSimulationTool(self):
+ return getToolByName(self.getPortal(), 'portal_simulation', None)
+
+ def getSQLConnection(self):
+ return getToolByName(self.getPortal(), 'erp5_sql_connection', None)
+
+ def getPortalId(self):
+ return self.getPortal().getId()
+
+ def getDomainTool(self):
+ return getToolByName(self.getPortal(), 'portal_domains', None)
+
+ def getAlarmTool(self):
+ return getattr(self.getPortal(), 'portal_alarms', None)
+
+ def getActivityTool(self):
+ return getattr(self.getPortal(), 'portal_activities', None)
+
+ def getArchiveTool(self):
+ return getattr(self.getPortal(), 'portal_archives', None)
+
+ def getCacheTool(self):
+ return getattr(self.getPortal(), 'portal_caches', None)
+
+ def getOrganisationModule(self):
+ return getattr(self.getPortal(), 'organisation_module',
+ getattr(self.getPortal(), 'organisation', None))
+
+ def getPersonModule(self):
+ return getattr(self.getPortal(), 'person_module',
+ getattr(self.getPortal(), 'person', None))
+
+ def getCurrencyModule(self):
+ return getattr(self.getPortal(), 'currency_module',
+ getattr(self.getPortal(), 'currency', None))
+
+ def _addPropertySheet(self, portal_type_name,
+ property_sheet_name='TestPropertySheet',
+ property_sheet_code=None):
+ """Utility method to add a property sheet to a type information.
+ You might be interested in the higer level method _addProperty
+ This method registers all added property sheets, to be able to remove
+ them in tearDown.
+ """
+ # install the 'real' class tool
+ class_tool = self.getClassTool()
+
+ if property_sheet_code is not None:
+ class_tool.newPropertySheet(property_sheet_name)
+ # XXX need to commit the transaction at this point, because class tool
+ # files are no longer available to the current transaction.
+ transaction.commit()
+ class_tool.editPropertySheet(property_sheet_name, property_sheet_code)
+ transaction.commit()
+ class_tool.importPropertySheet(property_sheet_name)
+
+ # We set the property sheet on the portal type
+ types_tool = self.getTypesTool()
+ ti = types_tool.getTypeInfo(portal_type_name)
+ property_sheet_set = set(ti.getTypePropertySheetList())
+ property_sheet_set.add(property_sheet_name)
+ ti._setTypePropertySheetList(list(property_sheet_set))
+
+ # remember that we added a property sheet for tear down
+ self._added_property_sheets.setdefault(
+ portal_type_name, []).append(property_sheet_name)
+ # reset aq_dynamic cache
+ types_tool.resetDynamicDocuments()
+
+ def getRule(self, **kw):
+ return self.portal.portal_rules.searchFolder(
+ sort_on='version', sort_order='descending', **kw)[0].getObject()
+
+ def validateRules(self):
+ """
+ try to validate all rules in rule_tool.
+ """
+ rule_tool = self.getRuleTool()
+ for rule in rule_tool.contentValues(
+ portal_type=rule_tool.getPortalRuleTypeList()):
+ if rule.getValidationState() != 'validated':
+ rule.validate()
+
+ def createSimpleUser(self, title, reference, function):
+ """
+ Helper function to create a Simple ERP5 User.
+ User password is the reference.
+ """
+ user = self.createUser(reference, person_kw=dict(title=title))
+ assignment = self.createUserAssignement(user, assignment_kw=dict(function=function))
+ return user
+
+ def createUser(self, reference, password=None, person_kw=None):
+ """
+ Create an ERP5 User.
+ Default password is the reference.
+ person_kw is passed as additional arguments when creating the person
+ """
+ if password is None:
+ password = reference
+ if person_kw is None:
+ person_kw = dict()
+
+ person = self.portal.person_module.newContent(portal_type='Person',
+ reference=reference,
+ password=password,
+ **person_kw)
+ return person
+
+ def createUserAssignment(self, user, assignment_kw):
+ """
+ Create an assignment to user.
+ """
+ assignment = user.newContent(portal_type='Assignment', **assignment_kw)
+ assignment.open()
+ return assignment
+
+ def createUserAssignement(self, user, assignment_kw):
+ # BBB
+ warn('createUserAssignement is deprecated;'
+ 'Use createUserAssignment instead',
+ DeprecationWarning)
+ return self.createUserAssignment(user, assignment_kw)
+
+ def failIfDifferentSet(self, a, b, msg=""):
+ if not msg:
+ msg='%r != %r' % (a, b)
+ self.assertEquals(set(a), set(b), msg)
+ assertSameSet = failIfDifferentSet
+
+ def assertWorkflowTransitionFails(self, object, workflow_id, transition_id,
+ error_message=None, state_variable='simulation_state'):
+ """
+ Check that passing given transition from given workflow on given object
+ raises ValidationFailed.
+ Do sanity checks (workflow history length increased by one, simulation
+ state unchanged).
+ If error_message is provided, it is asserted to be equal to the last
+ workflow history error message.
+ """
+ workflow_tool = self.getWorkflowTool()
+ reference_history_length = len(workflow_tool.getInfoFor(ob=object, name='history', wf_id=workflow_id))
+ state_method = 'get' + convertToUpperCase(state_variable)
+ method = getattr(object, state_method, None)
+ reference_workflow_state = method()
+ self.assertRaises(ValidationFailed, workflow_tool.doActionFor, object, transition_id, wf_id=workflow_id)
+ workflow_history = workflow_tool.getInfoFor(ob=object, name='history', wf_id=workflow_id)
+ self.assertEqual(len(workflow_history), reference_history_length + 1)
+ workflow_error_message = str(workflow_history[-1]['error_message'])
+ if error_message is not None:
+ self.assertEqual(workflow_error_message, error_message)
+ self.assertEqual(method(), reference_workflow_state)
+ return workflow_error_message
+
+ def stepPdb(self, sequence=None, sequence_list=None):
+ """Invoke debugger"""
+ try: # try ipython if available
+ import IPython
+ IPython.Shell.IPShell(argv=[])
+ tracer = IPython.Debugger.Tracer()
+ except ImportError:
+ from pdb import set_trace as tracer
+ tracer()
+
+ def stepTic(self, **kw):
+ """
+ The is used to simulate the zope_tic_loop script
+ Each time this method is called, it simulates a call to tic
+ which invoke activities in the Activity Tool
+ """
+ if kw.get('sequence', None) is None:
+ # in case of using not in sequence commit transaction
+ transaction.commit()
+ self.tic()
+
+ getPortalObject = getPortal
+
+ # class-defined decorators for profiling.
+ # Depending on the environment variable, they return
+ # the same method, or a profiling wrapped call
+ _decorate_setUp = profile_if_environ('PROFILE_SETUP')
+ _decorate_testRun = profile_if_environ('PROFILE_TESTS')
+ _decorate_tearDown = profile_if_environ('PROFILE_TEARDOWN')
+
+ def __call__(self, *args, **kw):
+ # Pulling down the profiling from ZopeTestCase.profiler to allow
+ # overriding run()
+ # This cannot be done at instanciation because we need to
+ # wrap the bottom-most methods, e.g.
+ # SecurityTestCase.tearDown instead of ERP5TestCase.tearDown
+
+ self.setUp = self._decorate_setUp(self.setUp)
+ self.tearDown = self._decorate_tearDown(self.tearDown)
+
+ test_name = self._testMethodName
+ test_method = getattr(self, test_name)
+ setattr(self, test_name, self._decorate_testRun(test_method))
+
+ self.run(*args, **kw)
+
+ def logMessage(self, message):
+ """
+ Shortcut function to log a message
+ """
+ ZopeTestCase._print('\n%s ' % message)
+ LOG('Testing ... ', DEBUG, message)
+
+ def publish(self, path, basic=None, env=None, extra=None,
+ request_method='GET', stdin=None, handle_errors=True):
+ '''Publishes the object at 'path' returning a response object.'''
+
+ from ZPublisher.Response import Response
+ from ZPublisher.Test import publish_module
+
+ from AccessControl.SecurityManagement import getSecurityManager
+ from AccessControl.SecurityManagement import setSecurityManager
+
+ # Save current security manager
+ sm = getSecurityManager()
+
+ # Commit the sandbox for good measure
+ transaction.commit()
+
+ if env is None:
+ env = {}
+ if extra is None:
+ extra = {}
+
+ request = self.app.REQUEST
+
+ env['SERVER_NAME'] = request['SERVER_NAME']
+ env['SERVER_PORT'] = request['SERVER_PORT']
+ env['HTTP_ACCEPT_CHARSET'] = request['HTTP_ACCEPT_CHARSET']
+ env['REQUEST_METHOD'] = request_method
+
+ p = path.split('?')
+ if len(p) == 1:
+ env['PATH_INFO'] = p[0]
+ elif len(p) == 2:
+ [env['PATH_INFO'], env['QUERY_STRING']] = p
+ else:
+ raise TypeError, ''
+
+ if basic:
+ env['HTTP_AUTHORIZATION'] = "Basic %s" % base64.encodestring(basic).replace('\012', '')
+
+ if stdin is None:
+ stdin = StringIO()
+
+ outstream = StringIO()
+ response = Response(stdout=outstream, stderr=sys.stderr)
+
+ publish_module('Zope2',
+ response=response,
+ stdin=stdin,
+ environ=env,
+ extra=extra,
+ debug=not handle_errors,
+ )
+
+ # Restore security manager
+ setSecurityManager(sm)
+
+ return ResponseWrapper(response, outstream, path)
+class ERP5TypeTestCase(ERP5TypeTestMixin):
+ """TestCase for ERP5 based tests.
+
+ This TestCase setups an ERP5Site and installs business templates.
+ """
+
+ def dummy_test(self):
+ ZopeTestCase._print('All tests are skipped when --save option is passed '
+ 'with --update_business_templates or without --load')
+
def getPortalName(self):
"""
Return the name of a portal for this test case.
@@ -337,8 +665,6 @@ class ERP5TypeTestCase(ProcessingNodeTes
setSite(portal)
return portal
- getPortalObject = getPortal
-
def _app(self):
'''Opens a ZODB connection and returns the app object.
@@ -366,49 +692,6 @@ class ERP5TypeTestCase(ProcessingNodeTes
"""
return 0
- def login(self, user_name='ERP5TypeTestCase', quiet=0):
- """
- Most of the time, we need to login before doing anything
- """
- PortalTestCase.login(self, user_name)
-
- def logout(self):
- PortalTestCase.logout(self)
- # clean up certain cache related REQUEST keys that might be associated
- # with the logged in user
- for key in ('_ec_cache', '_oai_cache'):
- self.REQUEST.other.pop(key, None)
-
- def _setupUser(self):
- '''Creates the default user.'''
- uf = self.portal.acl_users
- # do nothing if the user already exists
- if not uf.getUser(user_name):
- uf._doAddUser(user_name, 'secret', ['Member'], [])
-
- # class-defined decorators for profiling.
- # Depending on the environment variable, they return
- # the same method, or a profiling wrapped call
- _decorate_setUp = profile_if_environ('PROFILE_SETUP')
- _decorate_testRun = profile_if_environ('PROFILE_TESTS')
- _decorate_tearDown = profile_if_environ('PROFILE_TEARDOWN')
-
- def __call__(self, *args, **kw):
- # Pulling down the profiling from ZopeTestCase.profiler to allow
- # overriding run()
- # This cannot be done at instanciation because we need to
- # wrap the bottom-most methods, e.g.
- # SecurityTestCase.tearDown instead of ERP5TestCase.tearDown
-
- self.setUp = self._decorate_setUp(self.setUp)
- self.tearDown = self._decorate_tearDown(self.tearDown)
-
- test_name = self._testMethodName
- test_method = getattr(self, test_name)
- setattr(self, test_name, self._decorate_testRun(test_method))
-
- self.run(*args, **kw)
-
@staticmethod
def _getBTPathAndIdList(template_list):
bootstrap_path = os.environ.get('erp5_tests_bootstrap_path') or \
@@ -479,313 +762,112 @@ class ERP5TypeTestCase(ProcessingNodeTes
if uninstalled_list:
getattr(portal, 'ERP5Site_updateTranslationTable', lambda: None)()
self.stepTic()
- return uninstalled_list
-
- def setUp(self):
- '''Sets up the fixture. Do not override,
- use the hooks instead.
- '''
- from Products.CMFActivity.ActivityRuntimeEnvironment import BaseMessage
- # Activities in unit tests shall never fail.
- # Let's be a litte tolerant for the moment.
- BaseMessage.max_retry = property(lambda self:
- self.activity_kw.get('max_retry', 1))
-
- use_dummy_mail_host = os.environ.get('use_dummy_mail_host', 0)
- template_list = self.getBusinessTemplateList()
- erp5_catalog_storage = os.environ.get('erp5_catalog_storage',
- 'erp5_mysql_innodb_catalog')
- update_business_templates = os.environ.get('update_business_templates') is not None
- erp5_load_data_fs = int(os.environ.get('erp5_load_data_fs', 0))
- if update_business_templates and erp5_load_data_fs:
- update_only = os.environ.get('update_only', None)
- template_list = (erp5_catalog_storage, 'erp5_core',
- 'erp5_xhtml_style') + tuple(template_list)
- # Update only specified business templates, regular expression
- # can be used.
- if update_only is not None:
- update_only_list = update_only.split(',')
- matching_template_list = []
- # First parse the template list in order to keep same order
- for business_template in template_list:
- for expression in update_only_list:
- if re.search(expression, business_template):
- matching_template_list.append(business_template)
- template_list = matching_template_list
-
- # keep a mapping type info name -> property sheet list, to remove them in
- # tear down.
- self._added_property_sheets = {}
- light_install = self.enableLightInstall()
- create_activities = self.enableActivityTool()
- hot_reindexing = self.enableHotReindexing()
- self.setUpERP5Site(business_template_list=template_list,
- light_install=light_install,
- create_activities=create_activities,
- quiet=install_bt5_quiet,
- hot_reindexing=hot_reindexing,
- erp5_catalog_storage=erp5_catalog_storage,
- use_dummy_mail_host=use_dummy_mail_host)
- PortalTestCase.setUp(self)
-
- def afterSetUp(self):
- '''Called after setUp() has completed. This is
- far and away the most useful hook.
- '''
- pass
-
- def getBusinessTemplateList(self):
- """
- You must override this. Return the list of business templates.
- """
- return ()
-
- def logMessage(self, message):
- """
- Shortcut function to log a message
- """
- ZopeTestCase._print('\n%s ' % message)
- LOG('Testing ... ', DEBUG, message)
-
- def _updateConnectionStrings(self):
- """Update connection strings with values passed by the testRunner
- """
- # update connection strings
- for connection_string_name, connection_string in\
- _getConnectionStringDict().items():
- connection_name = connection_string_name.replace('_string', '')
- getattr(self.portal, connection_name).edit('', connection_string)
-
- def _setUpDummyMailHost(self):
- """Replace Original Mail Host by Dummy Mail Host.
- """
- if 'MailHost' in self.portal.objectIds():
- self.portal.manage_delObjects(['MailHost'])
- self.portal._setObject('MailHost', DummyMailHost('MailHost'))
-
- def _updateConversionServerConfiguration(self):
- """Update conversion server (Oood) at default site preferences.
- """
- conversion_dict = _getConversionServerDict()
- preference = self.portal.portal_preferences[
- self.getDefaultSitePreferenceId()]
- preference._setPreferredOoodocServerAddress(conversion_dict['hostname'])
- preference._setPreferredOoodocServerPortNumber(conversion_dict['port'])
-
- def getDefaultSitePreferenceId(self):
- """Default id, usefull method to override
- """
- return "default_site_preference"
-
- def _recreateCatalog(self, quiet=0):
- """Clear activities and catalog and recatalog everything.
- Test runner can set `erp5_tests_recreate_catalog` environnement variable,
- in that case we have to clear catalog. """
- if int(os.environ.get('erp5_tests_recreate_catalog', 0)):
- try:
- _start = time.time()
- if not quiet:
- ZopeTestCase._print('\nRecreating catalog ... ')
- portal = self.getPortal()
- portal.portal_activities.manageClearActivities()
- portal.portal_catalog.manage_catalogClear()
- transaction.commit()
- portal.ERP5Site_reindexAll()
- transaction.commit()
- self.tic()
- if not quiet:
- ZopeTestCase._print('done (%.3fs)\n' % (time.time() - _start,))
- finally:
- os.environ['erp5_tests_recreate_catalog'] = '0'
-
- # Utility methods specific to ERP5Type
- def getTemplateTool(self):
- return getToolByName(self.getPortal(), 'portal_templates', None)
-
- def getPreferenceTool(self) :
- return getToolByName(self.getPortal(), 'portal_preferences', None)
-
- def getTrashTool(self):
- return getToolByName(self.getPortal(), 'portal_trash', None)
-
- def getPasswordTool(self):
- return getToolByName(self.getPortal(), 'portal_password', None)
-
- def getSkinsTool(self):
- return getToolByName(self.getPortal(), 'portal_skins', None)
-
- def getCategoryTool(self):
- return getToolByName(self.getPortal(), 'portal_categories', None)
-
- def getWorkflowTool(self):
- return getToolByName(self.getPortal(), 'portal_workflow', None)
-
- def getCatalogTool(self):
- return getToolByName(self.getPortal(), 'portal_catalog', None)
-
- def getTypesTool(self):
- return getToolByName(self.getPortal(), 'portal_types', None)
- getTypeTool = getTypesTool
-
- def getRuleTool(self):
- return getattr(self.getPortal(), 'portal_rules', None)
-
- def getClassTool(self):
- return getattr(self.getPortal(), 'portal_classes', None)
-
- def getSimulationTool(self):
- return getToolByName(self.getPortal(), 'portal_simulation', None)
-
- def getSQLConnection(self):
- return getToolByName(self.getPortal(), 'erp5_sql_connection', None)
-
- def getPortalId(self):
- return self.getPortal().getId()
-
- def getDomainTool(self):
- return getToolByName(self.getPortal(), 'portal_domains', None)
-
- def getAlarmTool(self):
- return getattr(self.getPortal(), 'portal_alarms', None)
-
- def getActivityTool(self):
- return getattr(self.getPortal(), 'portal_activities', None)
-
- def getArchiveTool(self):
- return getattr(self.getPortal(), 'portal_archives', None)
-
- def getCacheTool(self):
- return getattr(self.getPortal(), 'portal_caches', None)
-
- def getOrganisationModule(self):
- return getattr(self.getPortal(), 'organisation_module',
- getattr(self.getPortal(), 'organisation', None))
-
- def getPersonModule(self):
- return getattr(self.getPortal(), 'person_module',
- getattr(self.getPortal(), 'person', None))
-
- def getCurrencyModule(self):
- return getattr(self.getPortal(), 'currency_module',
- getattr(self.getPortal(), 'currency', None))
-
- def _addPropertySheet(self, portal_type_name,
- property_sheet_name='TestPropertySheet',
- property_sheet_code=None):
- """Utility method to add a property sheet to a type information.
- You might be interested in the higer level method _addProperty
- This method registers all added property sheets, to be able to remove
- them in tearDown.
- """
- # install the 'real' class tool
- class_tool = self.getClassTool()
-
- if property_sheet_code is not None:
- class_tool.newPropertySheet(property_sheet_name)
- # XXX need to commit the transaction at this point, because class tool
- # files are no longer available to the current transaction.
- transaction.commit()
- class_tool.editPropertySheet(property_sheet_name, property_sheet_code)
- transaction.commit()
- class_tool.importPropertySheet(property_sheet_name)
+ return uninstalled_list
- # We set the property sheet on the portal type
- types_tool = self.getTypesTool()
- ti = types_tool.getTypeInfo(portal_type_name)
- property_sheet_set = set(ti.getTypePropertySheetList())
- property_sheet_set.add(property_sheet_name)
- ti._setTypePropertySheetList(list(property_sheet_set))
+ def setUp(self):
+ '''Sets up the fixture. Do not override,
+ use the hooks instead.
+ '''
+ from Products.CMFActivity.ActivityRuntimeEnvironment import BaseMessage
+ # Activities in unit tests shall never fail.
+ # Let's be a litte tolerant for the moment.
+ BaseMessage.max_retry = property(lambda self:
+ self.activity_kw.get('max_retry', 1))
- # remember that we added a property sheet for tear down
- self._added_property_sheets.setdefault(
- portal_type_name, []).append(property_sheet_name)
- # reset aq_dynamic cache
- types_tool.resetDynamicDocuments()
+ use_dummy_mail_host = os.environ.get('use_dummy_mail_host', 0)
+ template_list = self.getBusinessTemplateList()
+ erp5_catalog_storage = os.environ.get('erp5_catalog_storage',
+ 'erp5_mysql_innodb_catalog')
+ update_business_templates = os.environ.get('update_business_templates') is not None
+ erp5_load_data_fs = int(os.environ.get('erp5_load_data_fs', 0))
+ if update_business_templates and erp5_load_data_fs:
+ update_only = os.environ.get('update_only', None)
+ template_list = (erp5_catalog_storage, 'erp5_core',
+ 'erp5_xhtml_style') + tuple(template_list)
+ # Update only specified business templates, regular expression
+ # can be used.
+ if update_only is not None:
+ update_only_list = update_only.split(',')
+ matching_template_list = []
+ # First parse the template list in order to keep same order
+ for business_template in template_list:
+ for expression in update_only_list:
+ if re.search(expression, business_template):
+ matching_template_list.append(business_template)
+ template_list = matching_template_list
- def getRule(self, **kw):
- return self.portal.portal_rules.searchFolder(
- sort_on='version', sort_order='descending', **kw)[0].getObject()
+ # keep a mapping type info name -> property sheet list, to remove them in
+ # tear down.
+ self._added_property_sheets = {}
+ light_install = self.enableLightInstall()
+ create_activities = self.enableActivityTool()
+ hot_reindexing = self.enableHotReindexing()
+ self.setUpERP5Site(business_template_list=template_list,
+ light_install=light_install,
+ create_activities=create_activities,
+ quiet=install_bt5_quiet,
+ hot_reindexing=hot_reindexing,
+ erp5_catalog_storage=erp5_catalog_storage,
+ use_dummy_mail_host=use_dummy_mail_host)
+ PortalTestCase.setUp(self)
- def validateRules(self):
- """
- try to validate all rules in rule_tool.
- """
- rule_tool = self.getRuleTool()
- for rule in rule_tool.contentValues(
- portal_type=rule_tool.getPortalRuleTypeList()):
- if rule.getValidationState() != 'validated':
- rule.validate()
+ def afterSetUp(self):
+ '''Called after setUp() has completed. This is
+ far and away the most useful hook.
+ '''
+ pass
- def createSimpleUser(self, title, reference, function):
+ def getBusinessTemplateList(self):
"""
- Helper function to create a Simple ERP5 User.
- User password is the reference.
+ You must override this. Return the list of business templates.
"""
- user = self.createUser(reference, person_kw=dict(title=title))
- assignment = self.createUserAssignement(user, assignment_kw=dict(function=function))
- return user
+ return ()
- def createUser(self, reference, password=None, person_kw=None):
- """
- Create an ERP5 User.
- Default password is the reference.
- person_kw is passed as additional arguments when creating the person
+ def _updateConnectionStrings(self):
+ """Update connection strings with values passed by the testRunner
"""
- if password is None:
- password = reference
- if person_kw is None:
- person_kw = dict()
-
- person = self.portal.person_module.newContent(portal_type='Person',
- reference=reference,
- password=password,
- **person_kw)
- return person
+ # update connection strings
+ for connection_string_name, connection_string in\
+ _getConnectionStringDict().items():
+ connection_name = connection_string_name.replace('_string', '')
+ getattr(self.portal, connection_name).edit('', connection_string)
- def createUserAssignment(self, user, assignment_kw):
- """
- Create an assignment to user.
+ def _setUpDummyMailHost(self):
+ """Replace Original Mail Host by Dummy Mail Host.
"""
- assignment = user.newContent(portal_type='Assignment', **assignment_kw)
- assignment.open()
- return assignment
-
- def createUserAssignement(self, user, assignment_kw):
- # BBB
- warn('createUserAssignement is deprecated;'
- 'Use createUserAssignment instead',
- DeprecationWarning)
- return self.createUserAssignment(user, assignment_kw)
-
- def failIfDifferentSet(self, a, b, msg=""):
- if not msg:
- msg='%r != %r' % (a, b)
- self.assertEquals(set(a), set(b), msg)
- assertSameSet = failIfDifferentSet
+ if 'MailHost' in self.portal.objectIds():
+ self.portal.manage_delObjects(['MailHost'])
+ self.portal._setObject('MailHost', DummyMailHost('MailHost'))
- def assertWorkflowTransitionFails(self, object, workflow_id, transition_id,
- error_message=None, state_variable='simulation_state'):
- """
- Check that passing given transition from given workflow on given object
- raises ValidationFailed.
- Do sanity checks (workflow history length increased by one, simulation
- state unchanged).
- If error_message is provided, it is asserted to be equal to the last
- workflow history error message.
+ def _updateConversionServerConfiguration(self):
+ """Update conversion server (Oood) at default site preferences.
"""
- workflow_tool = self.getWorkflowTool()
- reference_history_length = len(workflow_tool.getInfoFor(ob=object, name='history', wf_id=workflow_id))
- state_method = 'get' + convertToUpperCase(state_variable)
- method = getattr(object, state_method, None)
- reference_workflow_state = method()
- self.assertRaises(ValidationFailed, workflow_tool.doActionFor, object, transition_id, wf_id=workflow_id)
- workflow_history = workflow_tool.getInfoFor(ob=object, name='history', wf_id=workflow_id)
- self.assertEqual(len(workflow_history), reference_history_length + 1)
- workflow_error_message = str(workflow_history[-1]['error_message'])
- if error_message is not None:
- self.assertEqual(workflow_error_message, error_message)
- self.assertEqual(method(), reference_workflow_state)
- return workflow_error_message
+ conversion_dict = _getConversionServerDict()
+ preference = self.portal.portal_preferences[
+ self.getDefaultSitePreferenceId()]
+ preference._setPreferredOoodocServerAddress(conversion_dict['hostname'])
+ preference._setPreferredOoodocServerPortNumber(conversion_dict['port'])
+
+ def _recreateCatalog(self, quiet=0):
+ """Clear activities and catalog and recatalog everything.
+ Test runner can set `erp5_tests_recreate_catalog` environnement variable,
+ in that case we have to clear catalog. """
+ if int(os.environ.get('erp5_tests_recreate_catalog', 0)):
+ try:
+ _start = time.time()
+ if not quiet:
+ ZopeTestCase._print('\nRecreating catalog ... ')
+ portal = self.getPortal()
+ portal.portal_activities.manageClearActivities()
+ portal.portal_catalog.manage_catalogClear()
+ transaction.commit()
+ portal.ERP5Site_reindexAll()
+ transaction.commit()
+ self.tic()
+ if not quiet:
+ ZopeTestCase._print('done (%.3fs)\n' % (time.time() - _start,))
+ finally:
+ os.environ['erp5_tests_recreate_catalog'] = '0'
def _installBusinessTemplateList(self, business_template_list,
light_install=True,
@@ -1003,27 +1085,6 @@ class ERP5TypeTestCase(ProcessingNodeTes
break
PortalTestCase.tearDown(self)
- def stepPdb(self, sequence=None, sequence_list=None):
- """Invoke debugger"""
- try: # try ipython if available
- import IPython
- IPython.Shell.IPShell(argv=[])
- tracer = IPython.Debugger.Tracer()
- except ImportError:
- from pdb import set_trace as tracer
- tracer()
-
- def stepTic(self, **kw):
- """
- The is used to simulate the zope_tic_loop script
- Each time this method is called, it simulates a call to tic
- which invoke activities in the Activity Tool
- """
- if kw.get('sequence', None) is None:
- # in case of using not in sequence commit transaction
- transaction.commit()
- self.tic()
-
def importObjectFromFile(self, container, relative_path, **kw):
"""Import an object from a file located in $TESTFILEDIR/input/"""
test_path = os.path.dirname(__file__)
@@ -1033,63 +1094,6 @@ class ERP5TypeTestCase(ProcessingNodeTes
obj.manage_afterClone(obj)
return obj
- def publish(self, path, basic=None, env=None, extra=None,
- request_method='GET', stdin=None, handle_errors=True):
- '''Publishes the object at 'path' returning a response object.'''
-
- from ZPublisher.Response import Response
- from ZPublisher.Test import publish_module
-
- from AccessControl.SecurityManagement import getSecurityManager
- from AccessControl.SecurityManagement import setSecurityManager
-
- # Save current security manager
- sm = getSecurityManager()
-
- # Commit the sandbox for good measure
- transaction.commit()
-
- if env is None:
- env = {}
- if extra is None:
- extra = {}
-
- request = self.app.REQUEST
-
- env['SERVER_NAME'] = request['SERVER_NAME']
- env['SERVER_PORT'] = request['SERVER_PORT']
- env['HTTP_ACCEPT_CHARSET'] = request['HTTP_ACCEPT_CHARSET']
- env['REQUEST_METHOD'] = request_method
-
- p = path.split('?')
- if len(p) == 1:
- env['PATH_INFO'] = p[0]
- elif len(p) == 2:
- [env['PATH_INFO'], env['QUERY_STRING']] = p
- else:
- raise TypeError, ''
-
- if basic:
- env['HTTP_AUTHORIZATION'] = "Basic %s" % base64.encodestring(basic).replace('\012', '')
-
- if stdin is None:
- stdin = StringIO()
-
- outstream = StringIO()
- response = Response(stdout=outstream, stderr=sys.stderr)
-
- publish_module('Zope2',
- response=response,
- stdin=stdin,
- environ=env,
- extra=extra,
- debug=not handle_errors,
- )
-
- # Restore security manager
- setSecurityManager(sm)
-
- return ResponseWrapper(response, outstream, path)
from Products.ERP5 import ERP5Site
ERP5Site.getBootstrapBusinessTemplateUrl = lambda bt_title: \
More information about the Erp5-report
mailing list