[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[dak/master] ORMObject: make validation more robust.



Signed-off-by: Torsten Werner <twerner@debian.org>
---
 daklib/dbconn.py          |   13 ++++++++++---
 tests/dbtest_ormobject.py |    6 ++++++
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/daklib/dbconn.py b/daklib/dbconn.py
index 4e5acc2..6317b58 100755
--- a/daklib/dbconn.py
+++ b/daklib/dbconn.py
@@ -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
diff --git a/tests/dbtest_ormobject.py b/tests/dbtest_ormobject.py
index d1c72de..0790e4c 100755
--- a/tests/dbtest_ormobject.py
+++ b/tests/dbtest_ormobject.py
@@ -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()
-- 
1.7.2.5


Reply to: