[Zope3-checkins] CVS: ZODB4/src/persistence/tests - test_persistence.py:1.7

Phillip J. Eby pje@telecommunity.com
Thu, 17 Apr 2003 14:38:54 -0400


Update of /cvs-repository/ZODB4/src/persistence/tests
In directory cvs.zope.org:/tmp/cvs-serv1443/src/persistence/tests

Modified Files:
	test_persistence.py 
Log Message:
Fix object state change bugs reported in Zope3 collector #107.  In the
presence of a broken DM 'setstate()' or 'register()' method, persistent
objects could end up in CHANGED state when they should have stayed in their
original state.  This is perhaps not a complete solution to the issue of
what an object's state should be in the presence of a failure, but it 
prevents the two current "silent failure" conditions where an object thinks
it's CHANGED, but is not actually registered with the DM.  Added test cases
to demonstrate the old behavior and ensure it doesn't come back.


=== ZODB4/src/persistence/tests/test_persistence.py 1.6 => 1.7 ===
--- ZODB4/src/persistence/tests/test_persistence.py:1.6	Fri Apr 11 17:59:54 2003
+++ ZODB4/src/persistence/tests/test_persistence.py	Thu Apr 17 14:38:53 2003
@@ -102,6 +102,37 @@
         p._p_changed = 1
         self.assertEqual(dm.called, 1)
 
+    def testRegistrationFailure(self):
+        p = self.klass()
+        p._p_oid = 1
+        dm = BrokenDM()
+        p._p_jar = dm
+        self.assertEqual(p._p_changed, 0)
+        self.assertEqual(dm.called, 0)
+        try:
+            p._p_changed = 1
+        except NotImplementedError:
+            pass
+        else:
+            raise AssertionError("Exception not propagated")
+        self.assertEqual(dm.called, 1)
+        self.assertEqual(p._p_changed, 0)
+
+    def testLoadFailure(self):
+        p = self.klass()
+        p._p_oid = 1
+        dm = BrokenDM()
+        p._p_jar = dm
+        p._p_deactivate()  # make it a ghost
+        
+        try:
+            p._p_changed = 0    # request unghostification
+        except NotImplementedError:
+            pass
+        else:
+            raise AssertionError("Exception not propagated")
+        self.assertEqual(p._p_changed, None)
+
     def testActivate(self):
         p = self.klass()
         dm = DM()
@@ -245,6 +276,15 @@
         self.called += 1
     def setstate(self, ob):
         ob.__setstate__({'x': 42})
+
+class BrokenDM(DM):
+
+    def register(self,ob):
+        self.called += 1
+        raise NotImplementedError
+
+    def setstate(self,ob):
+        raise NotImplementedError
 
 class PersistentTest(Test):
     klass = P