From: Torsten Werner Date: Wed, 23 Mar 2011 21:45:10 +0000 (+0100) Subject: ORMObject: make validation more robust. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=347c09103eb5aae32976f03e9a9a0e8d8b4afb86;p=dak ORMObject: make validation more robust. Signed-off-by: Torsten Werner --- diff --git a/daklib/dbconn.py b/daklib/dbconn.py index 4e5acc21..6317b584 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 d1c72de4..0790e4c7 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()