[Zope-CVS] CVS: Products/Ape/lib/apelib/tests - testscanner.py:1.2 testall.py:1.5 testimpl.py:1.2 testio.py:1.3 teststorage.py:1.5
Shane Hathaway
shane@zope.com
Wed, 30 Jul 2003 17:33:47 -0400
Update of /cvs-repository/Products/Ape/lib/apelib/tests
In directory cvs.zope.org:/tmp/cvs-serv5368/lib/apelib/tests
Modified Files:
testall.py testimpl.py testio.py teststorage.py
Added Files:
testscanner.py
Log Message:
Merged ape-scan-branch, sneaking in interface updates and minor reformatting.
Ape now watches the filesystem for changes to objects that Zope has in its
cache.
=== Products/Ape/lib/apelib/tests/testscanner.py 1.1 => 1.2 ===
--- /dev/null Wed Jul 30 17:33:45 2003
+++ Products/Ape/lib/apelib/tests/testscanner.py Wed Jul 30 17:33:08 2003
@@ -0,0 +1,183 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Cache scanner tests
+
+$Id$
+"""
+
+import unittest
+from time import time
+
+from apelib.zodb3.scanner import ScanControl
+
+
+class FakeRepository:
+
+ def freshen(self, d):
+ res = {}
+ for source in d.keys():
+ repo, location = source
+ if repo is not self:
+ raise AssertionError, "repo must be self"
+ if str(location) != location:
+ raise AssertionError, "location is expected to be a string"
+ # Always report a change
+ res[source] = 1001
+ return res
+
+
+class FakeStorage:
+
+ repo = FakeRepository()
+
+ def getSources(self, oid):
+ return {(self.repo, oid): 10}
+
+
+class ScanControlTests(unittest.TestCase):
+
+ def setUp(self):
+ ctl = self.ctl = ScanControl()
+ self.conn1 = ctl.newConnection()
+ self.conn2 = ctl.newConnection()
+
+ def testSetNewOIDs(self):
+ self.conn1.setOIDs([5, 8])
+ oids = list(self.ctl.oids.keys())
+ self.assertEqual(oids, [5, 8])
+ self.assertEqual(list(self.ctl.conn_oids.keys()), [self.conn1.conn_id])
+
+ def testSetMultipleConnectionOIDs(self):
+ self.conn1.setOIDs([5, 8])
+ self.conn2.setOIDs([8, 9])
+ oids = list(self.ctl.oids.keys())
+ self.assertEqual(oids, [5,8,9])
+ conns = list(self.ctl.conn_oids.keys())
+ self.assertEqual(conns, [self.conn1.conn_id, self.conn2.conn_id])
+
+ def testRemoveOIDs(self):
+ self.conn1.setOIDs([5, 8])
+ self.conn2.setOIDs([8, 9])
+ self.conn1.setOIDs([8])
+ oids = list(self.ctl.oids.keys())
+ self.assertEqual(oids, [8,9])
+ conns = list(self.ctl.conn_oids.keys())
+ self.assertEqual(conns, [self.conn1.conn_id, self.conn2.conn_id])
+
+ self.conn1.setOIDs([])
+ oids = list(self.ctl.oids.keys())
+ self.assertEqual(oids, [8,9])
+ self.assertEqual(list(self.ctl.conn_oids.keys()), [self.conn2.conn_id])
+
+
+class ScannerTests(unittest.TestCase):
+
+ def setUp(self):
+ ctl = self.ctl = ScanControl()
+ self.conn1 = ctl.newConnection()
+ self.conn2 = ctl.newConnection()
+ self.scanner = ctl.scanner
+ self.repo = FakeRepository()
+
+ def testAddSource(self):
+ new_sources = {(self.repo, '5'): 0}
+ self.scanner.setSources(5, new_sources)
+ self.assertEqual(len(self.scanner.future), 1)
+ self.assertEqual(self.scanner.future[5][0], new_sources)
+
+ def testChangeSources(self):
+ self.conn1.setOIDs([5])
+
+ old_sources = {(self.repo, '5'): 0}
+ self.scanner.setSources(5, old_sources)
+ self.assertEqual(len(self.scanner.future), 0)
+ self.assertEqual(len(self.scanner.current), 1)
+ self.assertEqual(self.scanner.current[5], old_sources)
+
+ new_sources = {(self.repo, '6'): 0, (self.repo, '7'): 0, }
+ self.scanner.setSources(5, new_sources)
+ self.assertEqual(len(self.scanner.future), 0)
+ self.assertEqual(len(self.scanner.current), 1)
+ self.assertEqual(self.scanner.current[5], new_sources)
+
+ def testRemoveOID(self):
+ self.conn1.setOIDs([5])
+ self.assertEqual(len(self.scanner.current), 1)
+ self.conn1.setOIDs([])
+ self.assertEqual(len(self.scanner.current), 0)
+
+ def testScan(self):
+ self.conn1.setOIDs([5])
+ new_sources = {(self.repo, '6'): 0, (self.repo, '7'): 0, }
+ self.scanner.setSources(5, new_sources)
+ to_invalidate = self.scanner.scan()
+ self.assertEqual(len(to_invalidate), 1)
+
+ def testPruneFuture(self):
+ # Simulate some data.
+ self.scanner.future[5] = ([], time()) # Should not be pruned
+ self.scanner.future[900] = ([], time() - 100000) # Should be pruned
+ self.scanner.pruneFuture()
+ self.assertEqual(len(self.scanner.future), 1)
+ self.assert_(self.scanner.future.has_key(5))
+
+ def testFindNewSources(self):
+ # Verify the scanner calls storage.getSources() and saves the result.
+ storage = FakeStorage()
+ self.scanner.setStorage(storage)
+ self.conn1.setOIDs([5])
+ expect_sources = storage.getSources(5)
+ self.assertEqual(self.scanner.current[5], expect_sources)
+
+ def testUseCachedSources(self):
+ # Verify the scanner uses previously cached sources when available.
+ repo = FakeRepository()
+ sources = {(repo, '999'): -1}
+ self.scanner.setSources(5, sources)
+ self.conn1.setOIDs([5])
+ self.assertEqual(self.scanner.current[5], sources)
+
+ def testUseCommittedSources(self):
+ # Verify the scanner sees sources according to transactions.
+ repo = FakeRepository()
+ sources = {(repo, '999'): -1}
+ self.scanner.setSources(5, sources)
+ self.conn1.setOIDs([5])
+ sources_2 = {(repo, '999'): -2}
+ self.scanner.setUncommittedSources(123, 5, sources_2)
+ # Uncommitted data should have no effect on sources
+ self.assertEqual(self.scanner.current[5], sources)
+ self.scanner.afterCommit(123)
+ # The scanner should have used data from the repo rather
+ # than "-2".
+ final_sources = self.scanner.current[5]
+ self.assertEqual(len(final_sources), 1)
+ self.assertEqual(final_sources.keys()[0], (repo, '999'))
+ self.assertEqual(final_sources.values()[0], 1001)
+
+ def testAbort(self):
+ # Verify the scanner ignores sources on transaction abort.
+ repo = FakeRepository()
+ sources = {(repo, '999'): -2}
+ self.scanner.setUncommittedSources(123, 5, sources)
+ self.assertEqual(self.scanner.uncommitted[123][5], sources)
+ self.scanner.afterAbort(123)
+ self.assert_(not self.scanner.uncommitted.has_key(123))
+ self.assert_(not self.scanner.current.has_key(123))
+ self.assert_(not self.scanner.future.has_key(123))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
=== Products/Ape/lib/apelib/tests/testall.py 1.4 => 1.5 ===
--- Products/Ape/lib/apelib/tests/testall.py:1.4 Wed Jul 9 11:40:08 2003
+++ Products/Ape/lib/apelib/tests/testall.py Wed Jul 30 17:33:08 2003
@@ -38,6 +38,7 @@
from testparams import ParamsTests
from testsqlimpl import ApelibSQLImplTests
from apelib.config.tests.test_minitables import MiniTableTests
+from testscanner import ScanControlTests, ScannerTests
import testzope2sql
sql_suite = testzope2sql.test_suite()
@@ -54,6 +55,8 @@
Zope2FSUnderscoreTests,
ParamsTests,
ApelibSQLImplTests,
+ ScanControlTests,
+ ScannerTests,
):
suite.addTest(unittest.makeSuite(klass, 'test'))
suite.addTest(sql_suite)
=== Products/Ape/lib/apelib/tests/testimpl.py 1.1 => 1.2 ===
--- Products/Ape/lib/apelib/tests/testimpl.py:1.1 Wed Apr 9 23:09:57 2003
+++ Products/Ape/lib/apelib/tests/testimpl.py Wed Jul 30 17:33:08 2003
@@ -21,6 +21,7 @@
from types import ListType, TupleType
from Interface import Interface
+from Interface.IInterface import IInterface
from Interface.Verify import verifyClass
@@ -35,9 +36,11 @@
raise
def _testAllInModule(self, m):
+ name = m.__name__
for attr, value in m.__dict__.items():
if (hasattr(value, '__implements__') and
- not Interface.isImplementedBy(value)):
+ not IInterface.isImplementedBy(value)
+ and getattr(value, '__module__', None) == name):
self._testObjectImpl(value)
def _testAllInPackage(self, p):
=== Products/Ape/lib/apelib/tests/testio.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/tests/testio.py:1.2 Mon May 26 22:19:13 2003
+++ Products/Ape/lib/apelib/tests/testio.py Wed Jul 30 17:33:08 2003
@@ -85,7 +85,7 @@
event, classified_state = obsys.serialize(keychain, ob)
gwsys.store(keychain, classified_state)
- cs, hash_value = gwsys.load(keychain)
+ event, cs, hash_value = gwsys.load(keychain)
ob2 = obsys.newObject(cs)
obsys.deserialize(keychain, ob2, cs)
self.assertEqual(ob.strdata, ob2.strdata)
=== Products/Ape/lib/apelib/tests/teststorage.py 1.4 => 1.5 ===
--- Products/Ape/lib/apelib/tests/teststorage.py:1.4 Mon May 26 15:33:16 2003
+++ Products/Ape/lib/apelib/tests/teststorage.py Wed Jul 30 17:33:08 2003
@@ -377,6 +377,14 @@
conn1.close()
+ def testGetSources(self):
+ sources = self.storage.getSources('\0' * 8)
+ self.assertEqual(sources, {})
+ # The test passed, but check for a false positive.
+ oid = self.storage._oid_encoder.encode(('nonexistent-oid',))
+ self.assertRaises(KeyError, self.storage.getSources, oid)
+
+
if __name__ == '__main__':
unittest.main()