[Zope-Checkins] CVS: Zope/lib/python/Products/Transience/tests - testTimeoutRelated.py:1.8 testTransientObjectContainer.py:1.10
Chris McDonough
chrism@zope.com
Thu, 20 Jun 2002 21:51:44 -0400
Update of /cvs-repository/Zope/lib/python/Products/Transience/tests
In directory cvs.zope.org:/tmp/cvs-serv20260/tests
Modified Files:
testTimeoutRelated.py testTransientObjectContainer.py
Log Message:
New TransientObjectContainer implementation.
Changes:
- More stable under high usage, especially in the face of
situations under which there are many ZODB conflict
errors. The previous implementation had stability problems
when many conflict errors were encountered; especially
conflicts that were generated as a result of a simultaneous
change to a subobject of the TOC (such as in the case of a Zope
application which makes heavy use of both frames and
sessions).
- More conflict-resistant. Instead of ignoring the likelihood
that multiple threads will attempt to perform the same actions
simultaneously in methods of the TOC (which often causes
conflicts), the new implementation attempts to avoid conflicts
by employing a chance-based housekeeping model. In this model,
one thread is "elected" by chance to do the kinds of tasks that
cause the most conflicts.
- Now uses a "timeslice" based model instead of a "ring" based
model. This also helps cut down on conflicts and makes
the code slighly less obfuscated (not much, though! ;-)
- Quite a few more comments in the code.
- Changes to the sessioning stresstest (which exposed the
bug that made me reimplement the TOC in the first place).
- Updates to unit tests.
- A "HowTransienceWorks.stx" document which attempts to
explain how the code works. It's not stellar, but
it's a start.
- Changes to the TransientObject class that the TOC
hands out (typically as a "session data object"), in order
to make invalidation less Rube-Goldberg-ish.
The structure of the TOC object has changed enough that in order to
maintain b/w compatibility, an in-place upgrade of "old" instances
is implied by running them with this code. "Upgraded" instances
are not backwards-incompatible, however, so folks can hopefully
move back and forth between Zope versions without much hassle.
=== Zope/lib/python/Products/Transience/tests/testTimeoutRelated.py 1.7 => 1.8 ===
+if __name__=='__main__':
+ sys.path.insert(0, '..')
+ sys.path.insert(0, '../../..')
+
import ZODB # in order to get Persistence.Persistent working
from Testing import makerequest
import Acquisition
@@ -74,7 +78,7 @@
sdo = self.app.sm.new_or_existing('TempObject')
la1 = sdo.getLastAccessed()
fauxtime.sleep(WRITEGRANULARITY + 1)
- sdo = self.app.sm['TempObject']
+ sdo = self.app.sm.get('TempObject')
assert sdo.getLastAccessed() > la1, (sdo.getLastAccessed(), la1)
class TestNotifications(TestBase):
@@ -90,13 +94,15 @@
self.app.sm.setDelNotificationTarget(delNotificationTarget)
sdo = self.app.sm.new_or_existing('TempObject')
timeout = self.timeout * 60
- fauxtime.sleep(timeout + (timeout * .33))
- try: sdo1 = self.app.sm['TempObject']
- except KeyError: pass
+ fauxtime.sleep(timeout + (timeout * .75))
+ sdo1 = self.app.sm.get('TempObject')
+ for x in range(1, 100):
+ # force the sdm to do housekeeping
+ self.app.sm._getCurrentBucket()
now = fauxtime.time()
k = sdo.get('endtime')
- assert type(k) == type(now)
- assert k <= now
+ assert (type(k) == type(now)), type(k)
+ assert k <= now, (k, now)
def addNotificationTarget(item, context):
item['starttime'] = fauxtime.time()
=== Zope/lib/python/Products/Transience/tests/testTransientObjectContainer.py 1.9 => 1.10 ===
import sys, os, time, random, unittest
+if __name__ == "__main__":
+ sys.path.insert(0, '../../..')
+
import ZODB
from Products.Transience.Transience import TransientObjectContainer,\
MaxTransientObjectsExceeded
@@ -23,7 +26,7 @@
import time as oldtime
import fauxtime
-class TestTransientObjectContainer(TestCase):
+class TestBase(TestCase):
def setUp(self):
Products.Transience.Transience.time = fauxtime
Products.Transience.TransientObject.time = fauxtime
@@ -36,6 +39,7 @@
Products.Transience.Transience.time = oldtime
Products.Transience.TransientObject.time = oldtime
+class TestTransientObjectContainer(TestBase):
def testGetItemFails(self):
self.assertRaises(KeyError, self._getitemfail)
@@ -280,6 +284,36 @@
except KeyError:
if self.t.has_key(x): assert 1==2,"failed to delete %s" % x
+ def testChangingTimeoutWorks(self):
+ # 1 minute
+ for x in range(10, 110):
+ self.t[x] = x
+ fauxtime.sleep(self.timeout * (self.errmargin+1))
+ assert len(self.t.keys()) == 0, len(self.t.keys())
+
+ # 2 minutes
+ self.t._setTimeout(self.timeout/60*2)
+ self.t._reset()
+ for x in range(10, 110):
+ self.t[x] = x
+ fauxtime.sleep(self.timeout)
+ assert len(self.t.keys()) == 100, len(self.t.keys())
+ fauxtime.sleep(self.timeout * (self.errmargin+1))
+ assert len(self.t.keys()) == 0, len(self.t.keys())
+
+ # 3 minutes
+ self.t._setTimeout(self.timeout/60*3)
+ self.t._reset()
+ for x in range(10, 110):
+ self.t[x] = x
+ fauxtime.sleep(self.timeout)
+ assert len(self.t.keys()) == 100, len(self.t.keys())
+ fauxtime.sleep(self.timeout)
+ assert len(self.t.keys()) == 100, len(self.t.keys())
+ fauxtime.sleep(self.timeout * (self.errmargin+1))
+ assert len(self.t.keys()) == 0, len(self.t.keys())
+
+
def testItemsGetExpired(self):
for x in range(10, 110):
self.t[x] = x
@@ -326,14 +360,14 @@
fauxtime.sleep(self.timeout * (self.errmargin+1))
assert len(self.t.keys()) == 0, len(self.t.keys())
- def testGetItemDelaysTimeout(self):
+ def testGetDelaysTimeout(self):
for x in range(10, 110):
self.t[x] = x
# current bucket will become old after we sleep for a while.
fauxtime.sleep(self.timeout/2)
# these items will be added to the new current bucket by getitem
for x in range(10, 110):
- self.t[x]
+ self.t.get(x)
fauxtime.sleep(self.timeout/2)
assert len(self.t.keys()) == 100, len(self.t.keys())
for x in range(10, 110):
@@ -344,7 +378,7 @@
self.t[x] = x
# current bucket will become old after we sleep for a while.
fauxtime.sleep(self.timeout/2)
- # these items will be added to the new current bucket by getitem
+ # these items will be added to the new current bucket by setitem
for x in range(10, 110):
self.t[x] = x + 1
fauxtime.sleep(self.timeout/2)
@@ -352,19 +386,6 @@
for x in range(10, 110):
assert self.t[x] == x + 1
- def testGetDelaysTimeout(self):
- for x in range(10, 110):
- self.t[x] = x
- # current bucket will become old after we sleep for a while.
- fauxtime.sleep(self.timeout/2)
- # these items will be added to the new current bucket by getitem
- for x in range(10, 110):
- self.t.get(x)
- fauxtime.sleep(self.timeout/2)
- assert len(self.t.keys()) == 100, len(self.t.keys())
- for x in range(10, 110):
- assert self.t[x] == x
-
def testLen(self):
added = {}
r = range(10, 1010)
@@ -428,6 +449,7 @@
def test_suite():
testsuite = makeSuite(TestTransientObjectContainer, 'test')
+ #testsuite = makeSuite(TestBase, 'test')
alltests = TestSuite((testsuite,))
return alltests