Commit 4ba39f69 authored by Chris McDonough's avatar Chris McDonough

Browser Id Manager is no longer __replaceable__ = UNIQUE, meaning

that other things named browser_id_manager can be created in subfolders.

Wrap transient data objects only in session data manager upon return.
Previously, they had been wrapped also in session data container.

Took out clever traversal error logging code in fear that it would
bloat the ZODB.

Added SessionDataManagerErr and BrowserIdManagerErr to API docs and
made them importable within a PythonScript.

Extended test suite with request-autopopulate tests.
parent 35a3c9ba
......@@ -75,7 +75,7 @@
#
############################################################################
__version__='$Revision: 1.5 $'[11:-2]
__version__='$Revision: 1.6 $'[11:-2]
import Globals
from Persistence import Persistent
from ZODB import TimeStamp
......@@ -138,8 +138,6 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
security.setPermissionDefault(ACCESS_CONTENTS_PERM,['Manager','Anonymous'])
security.setPermissionDefault(CHANGE_IDMGR_PERM, ['Manager'])
__replaceable__ = UNIQUE # singleton for now
__implements__ = (SessionInterfaces.BrowserIdManagerInterface, )
icon = 'misc_/Sessions/idmgr.gif'
......
......@@ -83,7 +83,7 @@ from Persistence import Persistent
from AccessControl.Owned import Owned
from AccessControl.Role import RoleManager
from App.Management import Tabs
from zLOG import LOG, WARNING
from zLOG import LOG, WARNING, BLATHER
from AccessControl import ClassSecurityInfo
import SessionInterfaces
from SessionPermissions import *
......@@ -234,13 +234,13 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs):
def _getSessionDataObject(self, key):
""" returns new or existing session data object """
container = self._getSessionDataContainer()
ob = container.new_or_existing(key)
ob = aq_base(container.new_or_existing(key))
return ob.__of__(self)
def _getSessionDataObjectByKey(self, key):
""" returns new or existing session data object """
container = self._getSessionDataContainer()
ob = container.get(key)
ob = aq_base(container.get(key))
if ob is not None:
return ob.__of__(self)
......@@ -249,10 +249,8 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs):
transactions for mounted storages. """
if self.obpath is None:
err = 'Session data container is unspecified in %s' % self.getId()
if DEBUG:
LOG('Session Tracking', 0, err)
LOG('Session Tracking', WARNING, err)
raise SessionIdManagerErr, err
# return an external data container
try:
# This should arguably use restrictedTraverse, but it
# currently fails for mounted storages. This might
......@@ -260,7 +258,7 @@ class SessionDataManager(Item, Implicit, Persistent, RoleManager, Owned, Tabs):
# unrestrictedTraverse is also much faster.
if DEBUG and not hasattr(self, '_v_wrote_dc_type'):
args = string.join(self.obpath, '/')
LOG('Session Tracking', 0,
LOG('Session Tracking', BLATHER,
'External data container at %s in use' % args)
self._v_wrote_dc_type = 1
return self.unrestrictedTraverse(self.obpath)
......@@ -303,24 +301,15 @@ class SessionDataManagerTraverser:
def __init__(self, requestSessionName, sdm):
self._requestSessionName = requestSessionName
self._sessionDataManager = sdm
self._v_errors=0
def __call__(self, container, request):
sdm = self._sessionDataManager.__of__(container)
# Yank our session & stuff into request
try:
sdm = self._sessionDataManager.__of__(container)
session = sdm.getSessionData
self._v_errors = 0
except:
errors = getattr(self,"_v_errors", 0)
if errors < 4:
LOG('Session Tracking', WARNING,'Session automatic traversal '
'failed to get session data', error=sys.exc_info())
if errors == 3:
LOG('Session Tracking', WARNING, 'Suppressing further '
'automatic session failure error messages on this thread')
self._v_errors = errors + 1
return # Throw our hands up but dont fail
msg = 'Session automatic traversal failed to get session data'
LOG('Session Tracking', WARNING, msg, error=sys.exc_info())
return
if self._requestSessionName is not None:
request.set_lazy(self._requestSessionName, session)
......@@ -243,4 +243,3 @@ class SessionDataManagerInterface(
Permission required: Access arbitrary user session data
"""
......@@ -85,11 +85,14 @@
"""
Session initialization routines
$Id: __init__.py,v 1.4 2001/11/05 21:15:47 matt Exp $
$Id: __init__.py,v 1.5 2001/11/21 22:36:21 chrism Exp $
"""
import ZODB # this is for testrunner to be happy
import BrowserIdManager
import SessionDataManager
from BrowserIdManager import BrowserIdManagerErr
from SessionDataManager import SessionDataManagerErr
def initialize(context):
context.registerClass(
......@@ -108,6 +111,20 @@ def initialize(context):
SessionDataManager.constructSessionDataManager)
)
context.registerHelp()
context.registerHelpTitle("Zope Help")
# do module security declarations so folks can use some of the
# module-level stuff in PythonScripts
#
# declare on behalf of Transience too, since ModuleSecurityInfo is too
# stupid for me to declare in two places without overwriting one set
# with the other. :-(
from AccessControl import ModuleSecurityInfo
security = ModuleSecurityInfo('Products')
security.declarePublic('Sessions')
security.declarePublic('Transience')
security = ModuleSecurityInfo('Products.Sessions')
security.declarePublic('BrowserIdManagerErr')
security.declarePublic('SessionDataManagerErr')
security = ModuleSecurityInfo('Products.Transience')
security.declarePublic('MaxTransientObjectsExceeded')
......@@ -82,11 +82,7 @@ Session API
- "Transient Object API":../../Transience/Help/TransienceInterfaces.py
"""
import Interface
class BrowserIdManagerInterface(
Interface.Base
):
class BrowserIdManagerInterface:
"""
Zope Browser Id Manager interface.
......@@ -128,7 +124,7 @@ class BrowserIdManagerInterface(
Permission required: Access contents information
Raises: BrowserIdManagerErr. If ill-formed browser id
Raises: BrowserIdManagerErr if ill-formed browser id
is found in REQUEST.
"""
......@@ -192,9 +188,7 @@ class BrowserIdManagerInterface(
a browser id namespace at the time of the call.
"""
class SessionDataManagerInterface(
Interface.Base
):
class SessionDataManagerInterface:
"""
Zope Session Data Manager interface.
......@@ -239,4 +233,26 @@ class SessionDataManagerInterface(
Permission required: Access arbitrary user session data
"""
class SessionDataManagerErr:
"""
Error raised during some session data manager operations, as
explained in the API documentation of the Session Data Manager.
This exception may be caught in PythonScripts. A successful
import of the exception for PythonScript use would need to be::
from Products.Sessions import SessionDataManagerErr
"""
class BrowserIdManagerErr:
"""
Error raised during some browser id manager operations, as
explained in the API documentation of the Browser Id Manager.
This exception may be caught in PythonScripts. A successful
import of the exception for PythonScript use would need to be::
from Products.Sessions import BrowserIdManagerErr
"""
......@@ -85,9 +85,9 @@
"""
Test suite for session id manager.
$Id: testBrowserIdManager.py,v 1.4 2001/11/20 16:08:10 chrism Exp $
$Id: testBrowserIdManager.py,v 1.5 2001/11/21 22:36:21 chrism Exp $
"""
__version__ = "$Revision: 1.4 $"[11:-2]
__version__ = "$Revision: 1.5 $"[11:-2]
import sys
if __name__ == "__main__":
......@@ -351,5 +351,5 @@ def test_suite():
return testsuite
if __name__ == '__main__':
runner = TextTestRunner()
runner = TextTestRunner(verbosity=9)
runner.run(test_suite())
......@@ -85,14 +85,15 @@
import sys, os, time
if __name__ == "__main__":
sys.path.insert(0, '../../..')
#os.chdir('../../..')
from Testing import makerequest
import ZODB # in order to get Persistence.Persistent working
from OFS.DTMLMethod import DTMLMethod
import Acquisition
from Acquisition import aq_base
from Products.Sessions.BrowserIdManager import BrowserIdManager
from Products.Sessions.SessionDataManager import \
SessionDataManager, SessionDataManagerErr
SessionDataManager, SessionDataManagerErr, SessionDataManagerTraverser
from Products.Transience.Transience import \
TransientObjectContainer, TransientObject
from Products.TemporaryFolder.TemporaryFolder import MountedTemporaryFolder
......@@ -103,8 +104,9 @@ import time, threading, whrandom
from cPickle import UnpickleableError
from ZODB.DemoStorage import DemoStorage
from OFS.Application import Application
from ZPublisher.BeforeTraverse import registerBeforeTraverse, \
unregisterBeforeTraverse
import sys
sys.setcheckinterval(200)
tf_name = 'temp_folder'
idmgr_name = 'browser_id_manager'
......@@ -139,7 +141,8 @@ def _populate(app):
toc = TransientObjectContainer(toc_name, title='Temporary '
'Transient Object Container', timeout_mins=20)
session_data_manager=SessionDataManager(id='session_data_manager',
path='/'+tf_name+'/'+toc_name, title='Session Data Manager')
path='/'+tf_name+'/'+toc_name, title='Session Data Manager',
requestName='TESTOFSESSION')
try: app._delObject(idmgr_name)
except AttributeError: pass
......@@ -150,6 +153,9 @@ def _populate(app):
try: app._delObject('session_data_manager')
except AttributeError: pass
try: app._delObject('index_html')
except AttributeError: pass
app._setObject(idmgr_name, bidmgr)
app._setObject('session_data_manager', session_data_manager)
......@@ -159,7 +165,11 @@ def _populate(app):
app.temp_folder._setObject(toc_name, toc)
get_transaction().commit()
# index_html necessary for publishing emulation for testAutoReqPopulate
app._setObject('index_html', DTMLMethod('', __name__='foo'))
get_transaction().commit()
class TestBase(TestCase):
def setUp(self):
db = _getDB()
......@@ -191,6 +201,11 @@ class TestSessionManager(TestBase):
sd = self.app.session_data_manager.getSessionData()
assert self.app.session_data_manager.hasSessionData()
def testSessionDataWrappedInSDM(self):
sd = self.app.session_data_manager.getSessionData(1)
assert aq_base(sd.aq_parent) is \
aq_base(self.app.session_data_manager), sd.aq_parent
def testNewSessionDataObjectIsValid(self):
sdType = type(TransientObject(1))
sd = self.app.session_data_manager.getSessionData()
......@@ -201,6 +216,7 @@ class TestSessionManager(TestBase):
sd = self.app.session_data_manager.getSessionData()
sd.invalidate()
assert hasattr(sd, '_invalid')
assert not sd.isValid()
def testBrowserIdIsSet(self):
sd = self.app.session_data_manager.getSessionData()
......@@ -215,29 +231,30 @@ class TestSessionManager(TestBase):
assert sd == bykeysd, (sd, bykeysd, token)
def testBadExternalSDCPath(self):
sdm = self.app.session_data_manager
# fake out webdav
self.app.session_data_manager.REQUEST['REQUEST_METHOD'] = 'GET'
self.app.session_data_manager.setContainerPath('/fudgeffoloo')
try:
self.app.session_data_manager.getSessionData()
except SessionDataManagerErr:
pass
else:
assert 1 == 2, self.app.session_data_manager.getSessionDataContainerPath()
sdm.REQUEST['REQUEST_METHOD'] = 'GET'
sdm.setContainerPath('/fudgeffoloo')
self.assertRaises(SessionDataManagerErr, self._testbadsdcpath)
def _testbadsdcpath(self):
self.app.session_data_manager.getSessionData()
def testInvalidateSessionDataObject(self):
sd = self.app.session_data_manager.getSessionData()
sdm = self.app.session_data_manager
sd = sdm.getSessionData()
sd['test'] = 'Its alive! Alive!'
sd.invalidate()
assert not self.app.session_data_manager.getSessionData().has_key('test')
assert not sdm.getSessionData().has_key('test')
def testGhostUnghostSessionManager(self):
sdm = self.app.session_data_manager
get_transaction().commit()
sd = self.app.session_data_manager.getSessionData()
sd = sdm.getSessionData()
sd.set('foo', 'bar')
self.app.session_data_manager._p_changed = None
sdm._p_changed = None
get_transaction().commit()
assert self.app.session_data_manager.getSessionData().get('foo') == 'bar'
assert sdm.getSessionData().get('foo') == 'bar'
def testSubcommit(self):
sd = self.app.session_data_manager.getSessionData()
......@@ -261,6 +278,20 @@ class TestSessionManager(TestBase):
sd.set('foo', aq_wrapped)
self.assertRaises(UnpickleableError, get_transaction().commit)
def testAutoReqPopulate(self):
self.app.REQUEST['PARENTS'] = [self.app]
self.app.REQUEST['URL'] = 'a'
self.app.REQUEST.traverse('/')
assert self.app.REQUEST.has_key('TESTOFSESSION')
def testUnlazifyAutoPopulated(self):
self.app.REQUEST['PARENTS'] = [self.app]
self.app.REQUEST['URL'] = 'a'
self.app.REQUEST.traverse('/')
sess = self.app.REQUEST['TESTOFSESSION']
sdType = type(TransientObject(1))
assert type(aq_base(sess)) is sdType, type(aq_base(sess))
def test_suite():
test_datamgr = makeSuite(TestSessionManager, 'test')
suite = TestSuite((test_datamgr,))
......
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