]> git.decadent.org.uk Git - dak.git/commitdiff
ORMObject: make validation more robust.
authorTorsten Werner <twerner@debian.org>
Wed, 23 Mar 2011 21:45:10 +0000 (22:45 +0100)
committerTorsten Werner <twerner@debian.org>
Wed, 23 Mar 2011 21:45:10 +0000 (22:45 +0100)
Signed-off-by: Torsten Werner <twerner@debian.org>
daklib/dbconn.py
tests/dbtest_ormobject.py

index 4e5acc216ee3d639d6be5e9afebdea74107e9b65..6317b5844467a260865d5c7c67996eda537d7822 100755 (executable)
@@ -204,7 +204,9 @@ class ORMObject(object):
                     # list
                     value = len(value)
                 elif hasattr(value, 'count'):
-                    # query
+                    # query (but not during validation)
+                    if self.in_validation:
+                        continue
                     value = value.count()
                 else:
                     raise KeyError('Do not understand property %s.' % property)
@@ -258,6 +260,8 @@ class ORMObject(object):
     validation_message = \
         "Validation failed because property '%s' must not be empty in object\n%s"
 
+    in_validation = False
+
     def validate(self):
         '''
         This function validates the not NULL constraints as returned by
@@ -272,8 +276,11 @@ class ORMObject(object):
                 getattr(self, property + '_id') is not None:
                 continue
             if not hasattr(self, property) or getattr(self, property) is None:
-                raise DBUpdateError(self.validation_message % \
-                    (property, str(self)))
+                # str() might lead to races due to a 2nd flush
+                self.in_validation = True
+                message = self.validation_message % (property, str(self))
+                self.in_validation = False
+                raise DBUpdateError(message)
 
     @classmethod
     @session_wrapper
index d1c72de4552ccd99ddef3e68e235195c44d5e9c8..0790e4c7ad27ad797be29033c845354e3e815254 100755 (executable)
@@ -3,6 +3,7 @@
 from db_test import DBDakTestCase
 
 from daklib.dbconn import Architecture, Suite
+from daklib.dak_exceptions import DBUpdateError
 
 try:
     # python >= 2.6
@@ -35,5 +36,10 @@ class ORMObjectTestCase(DBDakTestCase):
         architecture.suites = [sid, squeeze]
         self.assertTrue(re.search('"suites_count": 2', str(architecture)))
 
+    def test_validation(self):
+        suite = Suite()
+        self.session.add(suite)
+        self.assertRaises(DBUpdateError, self.session.flush)
+
 if __name__ == '__main__':
     unittest.main()