[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()