[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r9784 - in trunk/gnue-appserver: src tests
From: |
johannes |
Subject: |
[gnue] r9784 - in trunk/gnue-appserver: src tests |
Date: |
Wed, 26 Sep 2007 08:35:04 -0500 (CDT) |
Author: johannes
Date: 2007-09-26 08:35:03 -0500 (Wed, 26 Sep 2007)
New Revision: 9784
Modified:
trunk/gnue-appserver/src/data.py
trunk/gnue-appserver/tests/data.py
Log:
Fixed dirty reads ?!
Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py 2007-09-26 12:44:15 UTC (rev 9783)
+++ trunk/gnue-appserver/src/data.py 2007-09-26 13:35:03 UTC (rev 9784)
@@ -1264,17 +1264,17 @@
next_add = None
for backend_record in [self.__buildRecords(r) for r in self.__rawdata]:
-
# if there are any uncommitted new records, insert them at the
# correct position
if next_add is not None:
gnue_id = backend_record._row
- while next_add < SortRecord(gnue_id,
+ while next_add and next_add < SortRecord(gnue_id,
self.__getSortSequence(gnue_id)):
self.__add.pop(0)
self.__added += 1
yield record(self.__cache, self.__connections,
- self.__database, self.__getMasterTable(), next_add)
+ self.__database, self.__getMasterTable(),
+ next_add.row)
if self.__add:
next_add = SortRecord(self.__add[0],
self.__getSortSequence(self.__add[0]))
@@ -1287,7 +1287,17 @@
yield backend_record
+ # If there new records left yield them as well
+ while self.__add:
+ next = self.__add[0]
+ self.__add.pop(0)
+ self.__added += 1
+ yield record(self.__cache, self.__connections,
+ self.__database, self.__getMasterTable(), next)
+
+
+
# ---------------------------------------------------------------------------
# Close the record set
# ---------------------------------------------------------------------------
@@ -1650,16 +1660,17 @@
result = []
append = result.append
- for element in self.__order:
- field = element ['name']
- direction = element.get ('descending') or False
- ignorecase = element.get ('ignorecase') or False
- value = self.__getPathValue (row, self.__getPropertyPath (field))
+ if self.__order:
+ for element in self.__order:
+ field = element ['name']
+ direction = element.get ('descending') or False
+ ignorecase = element.get ('ignorecase') or False
+ value = self.__getPathValue (row, self.__getPropertyPath (field))
- if ignorecase and hasattr (value, 'lower'):
- value = value.lower ()
+ if ignorecase and hasattr (value, 'lower'):
+ value = value.lower ()
- append ((value, direction))
+ append ((value, direction))
return result
Modified: trunk/gnue-appserver/tests/data.py
===================================================================
--- trunk/gnue-appserver/tests/data.py 2007-09-26 12:44:15 UTC (rev 9783)
+++ trunk/gnue-appserver/tests/data.py 2007-09-26 13:35:03 UTC (rev 9784)
@@ -31,674 +31,683 @@
# TestCase for _cache class
# =============================================================================
-class CachingTestCase (unittest.TestCase):
- """
- TestCase for the low-level class _cache
- """
-
- # ---------------------------------------------------------------------------
- # Test Case Setup
- # ---------------------------------------------------------------------------
-
- def setUp (self):
+class CachingTestCase(unittest.TestCase):
"""
- Create a new instance of the cache
+ TestCase for the low-level class _cache
"""
- self.cache = data._cache ()
+ # -------------------------------------------------------------------------
+ # Test Case Setup
+ # -------------------------------------------------------------------------
+ def setUp(self):
+ """
+ Create a new instance of the cache
+ """
- # ---------------------------------------------------------------------------
- # Is the cache cleaned well ?
- # ---------------------------------------------------------------------------
+ self.cache = data._cache()
- def test_cacheClean (self):
- """
- Test if the cache is cleaned well
- """
- table = u'FOO'
- rows = [u'100', u'200']
+ # -------------------------------------------------------------------------
+ # Is the cache cleaned well ?
+ # -------------------------------------------------------------------------
- # Write data into clean cache. The cache should not be dirty at all
- for row in rows:
- self.cache.write_clean (table, row, [(u'foo', 1)])
+ def test_cacheClean(self):
+ """
+ Test if the cache is cleaned well
+ """
- result = self.__orderTables (self.cache.dirtyTables ())
- self.assertEqual (result, [])
- self.assertEqual (self.cache.inserted, {})
- self.assertEqual (self.cache.deleted, {})
+ table = u'FOO'
+ rows = [u'100', u'200']
- # Now write data to dirty cache, which will render the records as 'changed'
- for row in rows:
- self.cache.write_dirty (table, row, u'foo', 1)
+ # Write data into clean cache. The cache should not be dirty at all
+ for row in rows:
+ self.cache.write_clean(table, row, [(u'foo', 1)])
- self.cache.insertRecord (u'BAR', u'200')
- self.cache.initialized (u'BAR', u'200')
- self.cache.insertRecord (u'FOO', u'771')
- self.cache.initialized (u'FOO', u'771')
- self.cache.write_dirty (u'FOO', u'771', u'val', 5)
+ result = self.__orderTables(self.cache.dirtyTables())
+ self.assertEqual(result, [])
+ self.assertEqual(self.cache.inserted, {})
+ self.assertEqual(self.cache.deleted, {})
- result = self.__orderTables (self.cache.dirtyTables ())
- exp = [(u'BAR', u'200', 'initialized', [(u'gnue_id', u'200')]),
- (u'FOO', u'100', 'changed', [(u'foo', 1)]),
- (u'FOO', u'200', 'changed', [(u'foo', 1)]),
- (u'FOO', u'771', 'inserted', [(u'gnue_id', u'771'), (u'val', 5)])]
+ # Now write data to dirty cache, which will render the records as
+ # 'changed'
+ for row in rows:
+ self.cache.write_dirty(table, row, u'foo', 1)
- self.assertEqual (result, exp)
- self.assertEqual (self.cache.inserted, {u'BAR-200': (u'BAR', u'200'),
- u'FOO-771': (u'FOO', u'771')})
- self.assertEqual (self.cache.deleted, {})
+ self.cache.insertRecord(u'BAR', u'200')
+ self.cache.initialized(u'BAR', u'200')
+ self.cache.insertRecord(u'FOO', u'771')
+ self.cache.initialized(u'FOO', u'771')
+ self.cache.write_dirty(u'FOO', u'771', u'val', 5)
- # Cancelling the current atomic operation should make the cache clean again
- self.cache.cancel ()
+ result = self.__orderTables(self.cache.dirtyTables())
+ exp = [(u'BAR', u'200', 'initialized', [(u'gnue_id', u'200')]),
+ (u'FOO', u'100', 'changed', [(u'foo', 1)]),
+ (u'FOO', u'200', 'changed', [(u'foo', 1)]),
+ (u'FOO', u'771', 'inserted', [(u'gnue_id', u'771'),(u'val',
5)])]
- result = self.__orderTables (self.cache.dirtyTables ())
- self.assertEqual (result, [])
- self.assertEqual (self.cache.inserted, {})
- self.assertEqual (self.cache.deleted, {})
+ self.assertEqual(result, exp)
+ self.assertEqual(self.cache.inserted, {u'BAR-200': (u'BAR', u'200'),
+ u'FOO-771': (u'FOO', u'771')})
+ self.assertEqual(self.cache.deleted, {})
- # Insert another three records. One is changed into 'inserted' state,
- # another one is left at 'initialized' and the last one is left at
- # 'initializing'
- self.cache.clear ()
+ # Cancelling the current atomic operation should make the cache clean
+ # again
+ self.cache.cancel()
- self.cache.insertRecord (table, u'1')
- self.cache.initialized (table, u'1')
- self.cache.write_dirty (table, u'1', u'foo', 1)
+ result = self.__orderTables(self.cache.dirtyTables())
+ self.assertEqual(result, [])
+ self.assertEqual(self.cache.inserted, {})
+ self.assertEqual(self.cache.deleted, {})
- self.cache.insertRecord (table, u'2')
- self.cache.initialized (table, u'2')
+ # Insert another three records. One is changed into 'inserted' state,
+ # another one is left at 'initialized' and the last one is left at
+ # 'initializing'
+ self.cache.clear()
- self.cache.insertRecord (table, u'3')
+ self.cache.insertRecord(table, u'1')
+ self.cache.initialized(table, u'1')
+ self.cache.write_dirty(table, u'1', u'foo', 1)
- exp = [(table, u'1', 'inserted', [(u'foo', 1), (u'gnue_id', u'1')]),
- (table, u'2', 'initialized', [(u'gnue_id', u'2')]),
- (table, u'3', 'initializing', [(u'gnue_id', u'3')])]
- self.assertEqual (exp, self.__orderTables (self.cache.dirtyTables ()))
+ self.cache.insertRecord(table, u'2')
+ self.cache.initialized(table, u'2')
- self.cache.makeClean (table, u'1')
+ self.cache.insertRecord(table, u'3')
- # Now clear all 'clean' stuff
- exp = [(table, u'2', 'initialized', [(u'gnue_id', u'2')]),
- (table, u'3', 'initializing', [(u'gnue_id', u'3')])]
- self.cache.clear (True)
- self.assertEqual (exp, self.__orderTables (self.cache.dirtyTables ()))
+ exp = [(table, u'1', 'inserted', [(u'foo', 1), (u'gnue_id', u'1')]),
+ (table, u'2', 'initialized', [(u'gnue_id', u'2')]),
+ (table, u'3', 'initializing', [(u'gnue_id', u'3')])]
+ self.assertEqual(exp, self.__orderTables(self.cache.dirtyTables()))
- # And now everything should really go away
- self.cache.clear ()
- self.assertEqual (self.cache.dirtyTables (), {})
+ self.cache.makeClean(table, u'1')
+ # Now clear all 'clean' stuff
+ exp = [(table, u'2', 'initialized', [(u'gnue_id', u'2')]),
+ (table, u'3', 'initializing', [(u'gnue_id', u'3')])]
+ self.cache.clear(True)
+ self.assertEqual(exp, self.__orderTables(self.cache.dirtyTables()))
-
- # ---------------------------------------------------------------------------
- # Perform insertions
- # ---------------------------------------------------------------------------
+ # And now everything should really go away
+ self.cache.clear()
+ self.assertEqual(self.cache.dirtyTables(), {})
- def test_cacheInsertions (self):
- """
- Perform variouse test regarding data insertion
- """
- self.cache.clear ()
- table = u'table'
- row = u'100'
- row2 = u'200'
+ # -------------------------------------------------------------------------
+ # Perform insertions
+ # -------------------------------------------------------------------------
- # We cannot insert a record if it's already available
- self.cache.write_dirty (table, row, u'foo', 1)
- self.assertRaises (data.DuplicateRecordError, self.cache.insertRecord,
- table, row)
+ def test_cacheInsertions(self):
+ """
+ Perform variouse test regarding data insertion
+ """
- self.cache.clear ()
+ self.cache.clear()
- # Insert a record, change and confirm it
- self.cache.insertRecord (table, row)
- self.cache.initialized (table, row)
- self.cache.write_dirty (table, row, u'foo', 1)
- self.cache.confirm ()
+ table = u'table'
+ row = u'100'
+ row2 = u'200'
- result = self.__orderTables (self.cache.dirtyTables ())
- exp = [(table, row, 'inserted', [(u'foo', 1), (u'gnue_id', row)])]
- self.assertEqual (result, exp)
- self.assertEqual (self.cache.inserted, {u'table-100': (table, row)})
- self.assertEqual (self.cache.deleted, {})
+ # We cannot insert a record if it's already available
+ self.cache.write_dirty(table, row, u'foo', 1)
+ self.assertRaises(data.DuplicateRecordError, self.cache.insertRecord,
+ table, row)
- # change it again, and insert another row. We won't set the latter one to
- # initialized so it does not get into 'inserted' state
- self.cache.write_dirty (table, row, u'foo', 2)
- self.cache.insertRecord (table, row2)
- self.cache.write_dirty (table, row2, u'bar', 2)
+ self.cache.clear()
- result = self.__orderTables (self.cache.dirtyTables ())
- exp = [(table, row, 'inserted', [(u'foo', 2), (u'gnue_id', row)]),
- (table, row2, 'initializing', [(u'bar', 2), (u'gnue_id', row2)])]
- self.assertEqual (result, exp)
- self.assertEqual (self.cache.inserted, {u'table-100': (table, row),
- u'table-200': (table, row2)})
- self.assertEqual (self.cache.deleted, {})
+ # Insert a record, change and confirm it
+ self.cache.insertRecord(table, row)
+ self.cache.initialized(table, row)
+ self.cache.write_dirty(table, row, u'foo', 1)
+ self.cache.confirm()
- # Now delete the second record
- self.cache.deleteRecord (table, row2)
+ result = self.__orderTables(self.cache.dirtyTables())
+ exp = [(table, row, 'inserted', [(u'foo', 1), (u'gnue_id', row)])]
+ self.assertEqual(result, exp)
+ self.assertEqual(self.cache.inserted, {u'table-100': (table, row)})
+ self.assertEqual(self.cache.deleted, {})
- # After deleting the previously inserted record the only record left should
- # be the inserted one
- result = self.__orderTables (self.cache.dirtyTables ())
- exp = [(table, row, 'inserted', [(u'foo', 2), (u'gnue_id', row)]),
- (table, row2, 'deleted', [(u'bar', 2), (u'gnue_id', None)])]
- self.assertEqual (result, exp)
- self.assertEqual (self.cache.inserted, {u'table-100': (table, row)})
- self.assertEqual (self.cache.deleted, {})
+ # change it again, and insert another row. We won't set the latter one
to
+ # initialized so it does not get into 'inserted' state
+ self.cache.write_dirty(table, row, u'foo', 2)
+ self.cache.insertRecord(table, row2)
+ self.cache.write_dirty(table, row2, u'bar', 2)
- # cancel the atomic operation. This should give us the state from the last
- # call of confirm ()
- self.cache.cancel ()
+ result = self.__orderTables(self.cache.dirtyTables())
+ exp = [(table, row, 'inserted', [(u'foo', 2), (u'gnue_id', row)]),
+ (table, row2, 'initializing', [(u'bar', 2), (u'gnue_id',
row2)])]
+ self.assertEqual(result, exp)
+ self.assertEqual(self.cache.inserted, {u'table-100': (table, row),
+ u'table-200': (table, row2)})
+ self.assertEqual(self.cache.deleted, {})
+ # Now delete the second record
+ self.cache.deleteRecord(table, row2)
- result = self.__orderTables (self.cache.dirtyTables ())
- exp = [(table, row, 'inserted', [(u'foo', 1), (u'gnue_id', row)])]
- self.assertEqual (result, exp)
- self.assertEqual (self.cache.inserted, {u'table-100': (table, row)})
- self.assertEqual (self.cache.deleted, {})
+ # After deleting the previously inserted record the only record left
+ # should be the inserted one
+ result = self.__orderTables(self.cache.dirtyTables())
+ exp = [(table, row, 'inserted', [(u'foo', 2), (u'gnue_id', row)]),
+ (table, row2, 'deleted', [(u'bar', 2), (u'gnue_id', None)])]
+ self.assertEqual(result, exp)
+ self.assertEqual(self.cache.inserted, {u'table-100': (table, row)})
+ self.assertEqual(self.cache.deleted, {})
- # Now simulate a commit which uses makeClean () to make a given record
- # clean
- self.cache.makeClean (table, row)
- self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), [])
- self.assertEqual (self.cache.inserted, {})
- self.assertEqual (self.cache.deleted, {})
+ # cancel the atomic operation. This should give us the state from the
+ # last call of confirm()
+ self.cache.cancel()
- # Add a new record, confirm it and then delete it
- self.cache.clear ()
- self.cache.insertRecord (table, row)
- self.cache.initialized (table, row)
- self.cache.write_dirty (table, row, u'name', 'foobar')
- self.cache.confirm ()
+ result = self.__orderTables(self.cache.dirtyTables())
+ exp = [(table, row, 'inserted', [(u'foo', 1), (u'gnue_id', row)])]
+ self.assertEqual(result, exp)
+ self.assertEqual(self.cache.inserted, {u'table-100': (table, row)})
+ self.assertEqual(self.cache.deleted, {})
- exp = [(table, row, 'inserted', [(u'gnue_id', row), (u'name', 'foobar')])]
- self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), exp)
- self.assertEqual (self.cache.inserted, {u'table-100': (table, row)})
+ # Now simulate a commit which uses makeClean() to make a given record
+ # clean
+ self.cache.makeClean(table, row)
+ self.assertEqual(self.__orderTables(self.cache.dirtyTables()), [])
+ self.assertEqual(self.cache.inserted, {})
+ self.assertEqual(self.cache.deleted, {})
- self.cache.deleteRecord (table, row)
+ # Add a new record, confirm it and then delete it
+ self.cache.clear()
- exp = [(table, row, 'deleted', [(u'gnue_id', None), (u'name', 'foobar')])]
- self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), exp)
- self.assertEqual (self.cache.inserted, {})
- self.assertEqual (self.cache.deleted, {})
+ self.cache.insertRecord(table, row)
+ self.cache.initialized(table, row)
+ self.cache.write_dirty(table, row, u'name', 'foobar')
+ self.cache.confirm()
+ exp = [(table, row, 'inserted', [(u'gnue_id', row), (u'name',
'foobar')])]
+ self.assertEqual(self.__orderTables(self.cache.dirtyTables()), exp)
+ self.assertEqual(self.cache.inserted, {u'table-100': (table, row)})
+ self.cache.deleteRecord(table, row)
+ exp = [(table, row, 'deleted',
+ [(u'gnue_id', None), (u'name', 'foobar')])]
+ self.assertEqual(self.__orderTables(self.cache.dirtyTables()), exp)
+ self.assertEqual(self.cache.inserted, {})
+ self.assertEqual(self.cache.deleted, {})
- # ---------------------------------------------------------------------------
- # Perform tests with modifications of records
- # ---------------------------------------------------------------------------
- def test_cacheModification (self):
- """
- Perfrom tests with mixed modification operations
- """
+ # -------------------------------------------------------------------------
+ # Perform tests with modifications of records
+ # -------------------------------------------------------------------------
- self.cache.clear ()
+ def test_cacheModification(self):
+ """
+ Perfrom tests with mixed modification operations
+ """
- table = u'FOO'
- row = u'100'
+ self.cache.clear()
- # First add some clean data to the cache
- self.cache.write_clean (table, row, [(u'foo', 1)])
+ table = u'FOO'
+ row = u'100'
- # Now change an 'existing' record and cancel that operation
- self.cache.write_dirty (table, row, u'bar', 2)
- self.cache.write_dirty (table, row, u'foo', 100)
- self.cache.cancel ()
+ # First add some clean data to the cache
+ self.cache.write_clean(table, row, [(u'foo', 1)])
- # The cached (current) value of 'foo' should be still the clean value, and
- # there must not be any 'dirty' data atm
- self.assertEqual (self.cache.read (table, row, u'foo'), 1)
- self.assertEqual (self.cache.dirtyTables (), {})
+ # Now change an 'existing' record and cancel that operation
+ self.cache.write_dirty(table, row, u'bar', 2)
+ self.cache.write_dirty(table, row, u'foo', 100)
+ self.cache.cancel()
- # Change the record again; now it should have the state 'changed'
- self.cache.write_dirty (table, row, u'foo', 100)
- result = self.__orderTables (self.cache.dirtyTables ())
- exp = [(table, row, 'changed', [(u'foo', 100)])]
- self.assertEqual (result, exp)
- self.cache.confirm ()
+ # The cached (current) value of 'foo' should be still the clean value,
+ # and there must not be any 'dirty' data atm
+ self.assertEqual(self.cache.read(table, row, u'foo'), 1)
+ self.assertEqual(self.cache.dirtyTables(), {})
- # Calling initialized () for a record which wasn't inserted before must
- # raise an exception
- self.assertRaises (data.StateChangeError, self.cache.initialized,
- table, row)
+ # Change the record again; now it should have the state 'changed'
+ self.cache.write_dirty(table, row, u'foo', 100)
+ result = self.__orderTables(self.cache.dirtyTables())
+ exp = [(table, row, 'changed', [(u'foo', 100)])]
+ self.assertEqual(result, exp)
+ self.cache.confirm()
- # Now delete the record. It will change it's state and shows up in the
- # deletion queue
- self.cache.deleteRecord (table, row)
- exp2 = [(table, row, 'deleted', [(u'foo', 100), (u'gnue_id', None)])]
- self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), exp2)
- self.assertEqual (self.cache.deleted, {u'FOO-100': (table, row)})
+ # Calling initialized() for a record which wasn't inserted before must
+ # raise an exception
+ self.assertRaises(data.StateChangeError, self.cache.initialized,
+ table, row)
- # Cancel the delete operation; we should be again at the point of the last
- # confirmation
- self.cache.cancel ()
- result = self.__orderTables (self.cache.dirtyTables ())
- self.assertEqual (result, exp)
- self.assertEqual (self.cache.deleted, {})
+ # Now delete the record. It will change it's state and shows up in the
+ # deletion queue
+ self.cache.deleteRecord(table, row)
+ exp2 = [(table, row, 'deleted', [(u'foo', 100), (u'gnue_id', None)])]
+ self.assertEqual(self.__orderTables(self.cache.dirtyTables()), exp2)
+ self.assertEqual(self.cache.deleted, {u'FOO-100': (table, row)})
- # Make the changed record a clean record
- self.cache.makeClean (table, row)
- self.assertEqual (self.cache.dirtyTables (), {})
+ # Cancel the delete operation; we should be again at the point of the
+ # last confirmation
+ self.cache.cancel()
+ result = self.__orderTables(self.cache.dirtyTables())
+ self.assertEqual(result, exp)
+ self.assertEqual(self.cache.deleted, {})
- # Delting a record and afterwards adding the same key points out a bug in
- # appserver
- self.cache.deleteRecord (u'frog', u'dummy')
- self.assertRaises (data.DuplicateRecordError, self.cache.insertRecord,
- u'frog', u'dummy')
- expected = [(u'frog', u'dummy', 'deleted', [(u'gnue_id', None)])]
- self.assertEqual (self.__orderTables (self.cache.dirtyTables ()), expected)
- self.assertEqual (self.cache.inserted, {})
- self.assertEqual (self.cache.deleted, {u'frog-dummy': (u'frog', u'dummy')})
+ # Make the changed record a clean record
+ self.cache.makeClean(table, row)
+ self.assertEqual(self.cache.dirtyTables(), {})
- self.cache.cancel ()
- self.assertEqual (self.cache.dirtyTables (), {})
- self.assertEqual (self.cache.inserted, {})
- self.assertEqual (self.cache.deleted, {})
+ # Delting a record and afterwards adding the same key points out a bug
+ # in appserver
+ self.cache.deleteRecord(u'frog', u'dummy')
+ self.assertRaises(data.DuplicateRecordError, self.cache.insertRecord,
+ u'frog', u'dummy')
+ expected = [(u'frog', u'dummy', 'deleted', [(u'gnue_id', None)])]
+ self.assertEqual(self.__orderTables(self.cache.dirtyTables()),
expected)
+ self.assertEqual(self.cache.inserted, {})
+ self.assertEqual(self.cache.deleted,
+ {u'frog-dummy': (u'frog', u'dummy')})
+ self.cache.cancel()
+ self.assertEqual(self.cache.dirtyTables(), {})
+ self.assertEqual(self.cache.inserted, {})
+ self.assertEqual(self.cache.deleted, {})
- # ---------------------------------------------------------------------------
- # Prepare the given cache-ditctionary
- # ---------------------------------------------------------------------------
- def __orderTables (self, tables):
- """
- Convert the given cache-dictionary into a comparable order. This function
- creates a sequence of quadruples built from tablename, rowid, current state
- of that row in the cache and an ordered sequence of (field, value) pairs.
- This sequence is sorted as well as the sequence of field-values.
+ # -------------------------------------------------------------------------
+ # Prepare the given cache-ditctionary
+ # -------------------------------------------------------------------------
- @param tables: cache-dictionary of the form 'dict [table] [row] [field]'
- @return: ordered sequence [(table, row, state, [(field, value), ...]), ...
]
- """
+ def __orderTables(self, tables):
+ """
+ Convert the given cache-dictionary into a comparable order. This
+ function creates a sequence of quadruples built from tablename, rowid,
+ current state of that row in the cache and an ordered sequence of
+ (field, value) pairs. This sequence is sorted as well as the sequence
+ of field-values.
- result = []
-
- for (table, rows) in tables.items ():
- for (row, fields) in rows.items ():
- fseq = fields.items ()
- fseq.sort ()
+ @param tables: cache-dictionary of the form 'dict [table] [row]
[field]'
+ @return: ordered sequence [(table, row, state, [(field, value), ...]),
+ ... ]
+ """
- result.append ((table, row, self.cache.state (table, row), fseq))
+ result = []
- result.sort ()
+ for (table, rows) in tables.items():
+ for (row, fields) in rows.items():
+ fseq = fields.items()
+ fseq.sort()
- return result
+ result.append((table, row, self.cache.state(table, row), fseq))
+ result.sort()
+ return result
+
+
# =============================================================================
# TestCase for connection class
# =============================================================================
-class ConnectionTestCase (unittest.TestCase):
- """
- TestCase for the connection class (= low level layer for sessions)
- """
-
- # ---------------------------------------------------------------------------
- # Prepare the test case
- # ---------------------------------------------------------------------------
-
- def setUp (self):
+class ConnectionTestCase(unittest.TestCase):
"""
- Create two seperate connections instances (so we can simulate two
- concurrent sessions) and log into both (using 'gnue' as username and
- password).
+ TestCase for the connection class (= low level layer for sessions)
"""
- app = GClientApp.GClientApp (application = 'appserver',
- defaults = geasConfiguration.ConfigOptions)
+ # -------------------------------------------------------------------------
+ # Prepare the test case
+ # -------------------------------------------------------------------------
- # Fake the login to the default connection
- c = app.connections.getConnection ('gnue')
- c.parameters ['_username'] = 'gnue'
- c.parameters ['_password'] = 'gnue'
+ def setUp(self):
+ """
+ Create two seperate connections instances (so we can simulate two
+ concurrent sessions) and log into both (using 'gnue' as username and
+ password).
+ """
- conn = GConnections.GConnections (app.connections._location,
- app.connections._loginHandler,
- app.connections._loginOptions)
- c2 = conn.getConnection ('gnue')
- c2.parameters ['_username'] = 'gnue'
- c2.parameters ['_password'] = 'gnue'
+ app = GClientApp.GClientApp(application = 'appserver',
+ defaults =
geasConfiguration.ConfigOptions)
- self.connection = data.connection (app.connections, 'gnue')
- self.concurrent = data.connection (conn, 'gnue')
+ # Fake the login to the default connection
+ c = app.connections.getConnection('gnue')
+ c.parameters ['_username'] = 'gnue'
+ c.parameters ['_password'] = 'gnue'
- self.remove = []
+ conn = GConnections.GConnections(app.connections._location,
+ app.connections._loginHandler,
+ app.connections._loginOptions)
+ c2 = conn.getConnection('gnue')
+ c2.parameters ['_username'] = 'gnue'
+ c2.parameters ['_password'] = 'gnue'
+ self.connection = data.connection(app.connections, 'gnue')
+ self.concurrent = data.connection(conn, 'gnue')
- # ---------------------------------------------------------------------------
- # Run some tests on the connection instance
- # ---------------------------------------------------------------------------
+ self.remove = []
- def testConnection (self):
- """
- Perform all tests
- """
- # Run an unordered query
- content = {None: (u'address_person', None, None, [u'address_name'])}
- rs = self.connection.query (content, None, None)
+ # -------------------------------------------------------------------------
+ # Run some tests on the connection instance
+ # -------------------------------------------------------------------------
- self.assertEqual (len(rs), 4)
- e = [u'James Tiberius Kirk', u'Spock', u'Leonard H. McCoy',
- u'Pavel Andreievich Chekov']
- e.sort ()
- self.assertEqual (self.__rsToSeq (rs, [u'address_name'], True), e)
+ def testConnection(self):
+ """
+ Perform all tests
+ """
- # Run an ordered query
- content = {None: (u'address_person', None, None, [u'address_name'])}
- rs = self.connection.query (content, None, [{'name': u'address_name'}])
+ # Run an unordered query
+ content = {None: (u'address_person', None, None, [u'address_name'])}
+ rs = self.connection.query(content, None, None)
- self.assertEqual (len(rs), 4)
- e = [u'James Tiberius Kirk', u'Leonard H. McCoy',
- u'Pavel Andreievich Chekov', u'Spock']
- self.assertEqual (self.__rsToSeq (rs, [u'address_name']), e)
+ self.assertEqual(len(rs), 4)
+ e = [u'James Tiberius Kirk', u'Spock', u'Leonard H. McCoy',
+ u'Pavel Andreievich Chekov']
+ e.sort()
+ self.assertEqual(self.__rsToSeq(rs, [u'address_name'], True), e)
- # Run the same query again, and using a non-prefetched field
- rs = self.connection.query (content, None, [{'name': u'address_name',
- 'descending': True}])
- result = []
- for rec in rs:
- result.append ((rec.getField (u'address_name'), rec.getField
- (u'address_zip')))
- rs.close ()
+ # Run an ordered query
+ content = {None: (u'address_person', None, None, [u'address_name'])}
+ rs = self.connection.query(content, None, [{'name': u'address_name'}])
- e = [(u'Spock', u'4711'),
- (u'Pavel Andreievich Chekov', u'195251'),
- (u'Leonard H. McCoy', u'39216'),
- (u'James Tiberius Kirk', u'2002')]
+ self.assertEqual(len(rs), 4)
+ e = [u'James Tiberius Kirk', u'Leonard H. McCoy',
+ u'Pavel Andreievich Chekov', u'Spock']
+ self.assertEqual(self.__rsToSeq(rs, [u'address_name']), e)
- self.assertEqual (result, e)
+ # Run the same query again, and using a non-prefetched field
+ rs = self.connection.query(content, None, [{'name': u'address_name',
+ 'descending': True}])
+ result = []
+ for rec in rs:
+ result.append((rec.getField(u'address_name'),
+ rec.getField(u'address_zip')))
+ rs.close()
- print "Simple condition ..."
- # Run the query with a simple condition
- cond = ['like', ['field', u'address_zip'], ['const', '%1']]
- rs = self.connection.query (content, cond, [{'name': u'address_name'}])
+ e = [(u'Spock', u'4711'),
+ (u'Pavel Andreievich Chekov', u'195251'),
+ (u'Leonard H. McCoy', u'39216'),
+ (u'James Tiberius Kirk', u'2002')]
- result = self.__rsToSeq (rs, [u'address_name'])
- e = [u'Pavel Andreievich Chekov', u'Spock']
- self.assertEqual (result, e)
+ self.assertEqual(result, e)
- # -------------------------------------------------------------------------
- # Checking dirty reads
+ # Run the query with a simple condition
+ cond = ['like', ['field', u'address_zip'], ['const', '%1']]
+ rs = self.connection.query(content, cond, [{'name': u'address_name'}])
- print "Dirty reads ..."
- (orgCrew, orgData) = self.__getCrewMembers ()
- expected = [(u'James Tiberius Kirk', u'US'),
- (u'Leonard H. McCoy', u'US'),
- (u'Pavel Andreievich Chekov', u'RU'),
- (u'Spock', None)]
+ result = self.__rsToSeq(rs, [u'address_name'])
+ e = [u'Pavel Andreievich Chekov', u'Spock']
+ self.assertEqual(result, e)
- self.assertEqual (orgData, expected)
+ # ---------------------------------------------------------------------
+ # Checking dirty reads
- # Now, Doc McCoy moves to Austria
- austria = u'0000000000000000000000200000000F'
- orgCrew [1].putField (u'address_country', austria)
-
- # Spock will leave (for the moment)
- spocksId = orgCrew [-1].getField (u'gnue_id')
- self.connection.deleteRecord (u'address_person', spocksId)
+ (orgCrew, orgData) = self.__get_crew_members()
+ expected = [(u'James Tiberius Kirk', u'US'),
+ (u'Leonard H. McCoy', u'US'),
+ (u'Pavel Andreievich Chekov', u'RU'),
+ (u'Spock', None)]
- # And a new crew member signs on
- new = self.connection.insertRecord (u'address_person')
- new.initialized ()
- new.putField (u'address_name', u'Foobar')
- new.putField (u'address_zip', u'6890')
- new.putField (u'address_country', austria)
+ self.assertEqual(orgData, expected)
- # So running the previous query again
- (newCrew, newData) = self.__getCrewMembers ()
- expected = [(u'Foobar', u'AT'),
- (u'James Tiberius Kirk', u'US'),
- (u'Leonard H. McCoy', u'AT'),
- (u'Pavel Andreievich Chekov', u'RU')]
- self.assertEqual (expected, newData)
+ # Now, Doc McCoy moves to Austria
+ austria = u'0000000000000000000000200000000F'
+ orgCrew[1].putField(u'address_country', austria)
- # Now, there's another session doing the same request
- (secCrew, secData) = self.__getCrewMembers (self.concurrent)
+ # Spock will leave (for the moment)
+ spocksId = orgCrew[-1].getField(u'gnue_id')
+ self.connection.deleteRecord(u'address_person', spocksId)
- # Since the changes made before are not yet commited the second connection
- # should still get the original result
- self.assertEqual (orgData, secData)
+ # And a new crew member signs on
+ new = self.connection.insertRecord(u'address_person')
+ new.initialized()
+ new.putField(u'address_name', u'Foobar')
+ new.putField(u'address_zip', u'6890')
+ new.putField(u'address_country', austria)
- # Cancelling the running atomic operation should also yield the former
- # situation
- self.connection.cancelChanges ()
- (newCrew, newData) = self.__getCrewMembers ()
+ # So running the previous query again
+ (newCrew, newData) = self.__get_crew_members()
- self.assertEqual (orgData, newData)
+ expected = [(u'Foobar', u'AT'),
+ (u'James Tiberius Kirk', u'US'),
+ (u'Leonard H. McCoy', u'AT'),
+ (u'Pavel Andreievich Chekov', u'RU')]
+ self.assertEqual(expected, newData)
- # ---
- # and again, Doc McCoy moves to Austria
- austria = u'0000000000000000000000200000000F'
- orgCrew [1].putField (u'address_country', austria)
-
- # Spock will leave (for the moment)
- spocksId = orgCrew [-1].getField (u'gnue_id')
- self.connection.deleteRecord (u'address_person', spocksId)
- # And the captain becomes the senior of Checkov
- orgCrew [-2].putField (u'address_senior',
- u'00000000000000000000000000001100')
+ # Now, there's another session doing the same request
+ (secCrew, secData) = self.__get_crew_members(self.concurrent)
- # And a new crew member signs on
- new = self.connection.insertRecord (u'address_person')
- new.initialized ()
- new.putField (u'address_name', u'Foobar')
- new.putField (u'address_zip', u'6890')
- new.putField (u'address_country', austria)
+ # Since the changes made before are not yet commited the second
+ # connection should still get the original result
+ self.assertEqual(orgData, secData)
- oz = self.connection.insertRecord (u'address_country')
- oz.initialized ()
- oz.putField (u'address_code', u'OZ')
- oz.putField (u'address_name', u'Oz')
+ # Cancelling the running atomic operation should also yield the former
+ # situation
+ self.connection.cancelChanges()
- self.connection.confirmChanges ()
+ (newCrew, newData) = self.__get_crew_members()
- # make some more changes
- new.putField (u'address_name', u'buzzing the foobar')
- new.putField (u'address_children', 2)
+ self.assertEqual(orgData, newData)
- self.connection.deleteRecord (u'address_country', oz.getField (u'gnue_id'))
+ # ---
+ # and again, Doc McCoy moves to Austria
+ austria = u'0000000000000000000000200000000F'
+ orgCrew [1].putField(u'address_country', austria)
- # change zip of James T. Kirk
- orgCrew [0].putField (u'address_zip', u'0815')
+ # Spock will leave (for the moment)
+ spocksId = orgCrew [-1].getField(u'gnue_id')
+ self.connection.deleteRecord(u'address_person', spocksId)
- # and now cancel all that changes
- self.connection.cancelChanges ()
+ # And the captain becomes the senior of Checkov
+ orgCrew [-2].putField(u'address_senior',
+ u'00000000000000000000000000001100')
- (newCrew, newData) = self.__getCrewMembers ()
- expected = [(u'Foobar', u'AT'),
- (u'James Tiberius Kirk', u'US'),
- (u'Leonard H. McCoy', u'AT'),
- (u'Pavel Andreievich Chekov', u'RU')]
- self.assertEqual (expected, newData)
+ # And a new crew member signs on
+ new = self.connection.insertRecord(u'address_person')
+ new.initialized()
+ new.putField(u'address_name', u'Foobar')
+ new.putField(u'address_zip', u'6890')
+ new.putField(u'address_country', austria)
- # The address_country table should again contain the new country record
- content = {None: (u'address_country', None, None, [u'address_name'])}
- condition = {u'address_code': u'OZ'}
- resultSet = self.connection.query (content, condition, None)
- self.assertEqual ([u'Oz'], self.__rsToSeq (resultSet, [u'address_name']))
+ oz = self.connection.insertRecord(u'address_country')
+ oz.initialized()
+ oz.putField(u'address_code', u'OZ')
+ oz.putField(u'address_name', u'Oz')
- new.putField (u'address_country', oz.getField (u'gnue_id'))
+ self.connection.confirmChanges()
- # Doing a commit here means storing all changes, but also shows if data.py
- # does a proper sorting of insertions. This is because we've created the
- # new person before the new country (which is in fact a master record for
- # the person and theirfor must be added *before* the person).
- self.connection.commit ()
+ # make some more changes
+ new.putField(u'address_name', u'buzzing the foobar')
+ new.putField(u'address_children', 2)
- # Since the second session had no commit until now, no changes made by the
- # first session should be visible at all.
- (secCrew, secData) = self.__getCrewMembers (self.concurrent)
- expected = [(u'James Tiberius Kirk', u'US'),
- (u'Leonard H. McCoy', u'US'),
- (u'Pavel Andreievich Chekov', u'RU'),
- (u'Spock', None)]
- self.assertEqual (expected, secData)
+ self.connection.deleteRecord(u'address_country',
+ oz.getField(u'gnue_id'))
- # After closing the second session's transaction the query should now
- # return all changes made by the first session
- self.concurrent.rollback ()
+ # change zip of James T. Kirk
+ orgCrew [0].putField(u'address_zip', u'0815')
- (secCrew, secData) = self.__getCrewMembers (self.concurrent)
- expected = [(u'Foobar', u'OZ'),
- (u'James Tiberius Kirk', u'US'),
- (u'Leonard H. McCoy', u'AT'),
- (u'Pavel Andreievich Chekov', u'RU')]
- self.assertEqual (expected, secData)
+ # and now cancel all that changes
+ self.connection.cancelChanges()
- self.connection.setConstraints (u'address_person',
- {u'address_country': {u'address_country': True},
- u'address_person': {u'address_senior': True}})
+ (newCrew, newData) = self.__get_crew_members()
+ expected = [(u'Foobar', u'AT'),
+ (u'James Tiberius Kirk', u'US'),
+ (u'Leonard H. McCoy', u'AT'),
+ (u'Pavel Andreievich Chekov', u'RU')]
+ self.assertEqual(expected, newData)
- self.remove = [(u'address_person', new.getField (u'gnue_id')),
- (u'address_country', oz.getField (u'gnue_id'))]
+ # The address_country table should again contain the new country record
+ content = {None: (u'address_country', None, None, [u'address_name'])}
+ condition = {u'address_code': u'OZ'}
+ resultSet = self.connection.query(content, condition, None)
+ self.assertEqual([u'Oz'], self.__rsToSeq(resultSet, [u'address_name']))
+ new.putField(u'address_country', oz.getField(u'gnue_id'))
+ # Doing a commit here means storing all changes, but also shows if
+ # data.py does a proper sorting of insertions. This is because we've
+ # created the new person before the new country (which is in fact a
+ # master record for the person and theirfor must be added *before* the
+ # person).
+ self.connection.commit()
- # ---------------------------------------------------------------------------
- # Restore to the initial situation in the test database
- # ---------------------------------------------------------------------------
+ # Since the second session had no commit until now, no changes made by
+ # the first session should be visible at all.
+ (secCrew, secData) = self.__get_crew_members(self.concurrent)
+ expected = [(u'James Tiberius Kirk', u'US'),
+ (u'Leonard H. McCoy', u'US'),
+ (u'Pavel Andreievich Chekov', u'RU'),
+ (u'Spock', None)]
+ self.assertEqual(expected, secData)
- def tearDown (self):
- """
- Undo all changes made by the testcase
- """
+ # After closing the second session's transaction the query should now
+ # return all changes made by the first session
+ self.concurrent.rollback()
- self.connection.rollback ()
+ (secCrew, secData) = self.__get_crew_members(self.concurrent)
+ expected = [(u'Foobar', u'OZ'),
+ (u'James Tiberius Kirk', u'US'),
+ (u'Leonard H. McCoy', u'AT'),
+ (u'Pavel Andreievich Chekov', u'RU')]
+ self.assertEqual(expected, secData)
- # First we have to re-add the record for Spock
- spock = self.connection.insertRecord (u'address_person')
- spock.initialized ()
- spock.putField (u'address_name', u'Spock')
- spock.putField (u'address_street', u'Vulc Lane 1')
- spock.putField (u'address_zip', u'4711')
- spock.putField (u'address_city', u'Vulcane')
- spock.putField (u'address_children', 0)
- spock.putField (u'address_weight', 78.8)
- spock.putField (u'address_born', u'2230-01-01')
- spock.putField (u'address_meettime', u'6:30')
- spock.putField (u'address_lastmeeting', u'2270-05-17 08:00')
- spock.putField (u'address_human', False)
- spock.putField (u'address_senior', u'00000000000000000000000000001100')
- # This is a bit hackish cause we're changing the primary key
- spock.putField (u'gnue_id', u'00000000000000000000000000001101')
+ self.connection.setConstraints(u'address_person',
+ {u'address_country': {u'address_country': True},
+ u'address_person': {u'address_senior': True}})
- # Reset the country for McCoy to the US
- mccoy = self.connection.findRecord (u'address_person',
- u'00000000000000000000000000001102', [u'address_country'])
- mccoy.putField (u'address_country', u'000000000000000000000020000000E3')
+ self.remove = [(u'address_person', new.getField(u'gnue_id')),
+ (u'address_country', oz.getField(u'gnue_id'))]
- # Reassign Spock as Checkov's senior
- checkov = self.connection.findRecord (u'address_person',
- u'00000000000000000000000000001103', [u'address_senior'])
- checkov.putField (u'address_senior', u'00000000000000000000000000001101')
- # And remove newly added records
- for (table, row) in self.remove:
- self.connection.deleteRecord (table, row)
- self.connection.commit ()
+ # -------------------------------------------------------------------------
+ # Restore to the initial situation in the test database
+ # -------------------------------------------------------------------------
+ def tearDown(self):
+ """
+ Undo all changes made by the testcase
+ """
+ self.connection.rollback()
- # ---------------------------------------------------------------------------
- # Create a list of records and it's data for all crew members
- # ---------------------------------------------------------------------------
+ # First we have to re-add the record for Spock
+ spock = self.connection.insertRecord(u'address_person')
+ spock.initialized()
+ spock.putField(u'address_name', u'Spock')
+ spock.putField(u'address_street', u'Vulc Lane 1')
+ spock.putField(u'address_zip', u'4711')
+ spock.putField(u'address_city', u'Vulcane')
+ spock.putField(u'address_children', 0)
+ spock.putField(u'address_weight', 78.8)
+ spock.putField(u'address_born', u'2230-01-01')
+ spock.putField(u'address_meettime', u'6:30')
+ spock.putField(u'address_lastmeeting', u'2270-05-17 08:00')
+ spock.putField(u'address_human', False)
+ spock.putField(u'address_senior', u'00000000000000000000000000001100')
+ # This is a bit hackish cause we're changing the primary key
+ spock.putField(u'gnue_id', u'00000000000000000000000000001101')
- def __getCrewMembers (self, connection = None):
- """
- Create a list of records and it's data for all crew members
+ # Reset the country for McCoy to the US
+ mccoy = self.connection.findRecord(u'address_person',
+ u'00000000000000000000000000001102',
+ [u'address_country'])
+ mccoy.putField(u'address_country', u'000000000000000000000020000000E3')
- @param connection: if given this connection instance will be used. It
- defaults to 'self.connection'.
+ # Reassign Spock as Checkov's senior
+ checkov = self.connection.findRecord(u'address_person',
+ u'00000000000000000000000000001103', [u'address_senior'])
+ checkov.putField(u'address_senior',
u'00000000000000000000000000001101')
- @return: tuple (recordlist, datalist), where recordlist is a sequence of
- data.record instances, and datalist is a sequence of tuples
- (name, country-code), one per record found.
- """
+ # And remove newly added records
+ for (table, row) in self.remove:
+ self.connection.deleteRecord(table, row)
- if connection is None:
- connection = self.connection
+ self.connection.commit()
- # The following content definition drives 'address_person' as master table
- # and joins 'address_country' in a left outer join, where 'address_name' is
- # the onyle prefetched field for both tables. This forces data.py to do
- # refetching for the joined table (cause we're accessing 'address_code').
- content = {u't0': (u'address_person', None, None, [u'address_name']),
- u't1': (u'address_country', u't0', u'address_country',
- [u'address_name'])}
- sortOrder = [{'name': u't0.address_name'}]
- resultSet = connection.query (content, None, sortOrder)
- recList = []
- recData = []
- for rec in resultSet:
- country = rec.getField (u'address_country')
- if country is not None:
- jRec = connection.findRecord (u'address_country', country, [])
- cCode = jRec.getField (u'address_code')
- else:
- cCode = None
+ # -------------------------------------------------------------------------
+ # Create a list of records and it's data for all crew members
+ # -------------------------------------------------------------------------
- recData.append ((rec.getField (u'address_name'), cCode))
+ def __get_crew_members(self, connection=None):
+ """
+ Create a list of records and it's data for all crew members
- recList.append (rec)
+ @param connection: if given this connection instance will be used. It
+ defaults to 'self.connection'.
- resultSet.close ()
+ @return: tuple (recordlist, datalist), where recordlist is a sequence
+ of data.record instances, and datalist is a sequence of tuples
+ (name, country-code), one per record found.
+ """
- return (recList, recData)
+ if connection is None:
+ connection = self.connection
+ # The following content definition drives 'address_person' as master
+ # table and joins 'address_country' in a left outer join, where
+ # 'address_name' is the only prefetched field for both tables. This
+ # forces data.py to do refetching for the joined table (cause we're
+ # accessing 'address_code').
+ content = {u't0': (u'address_person', None, None, [u'address_name']),
+ u't1': (u'address_country', u't0', u'address_country',
+ [u'address_name'])}
- # ---------------------------------------------------------------------------
- # Convert a resultSet into a flat sequence
- # ---------------------------------------------------------------------------
+ sortOrder = [{'name': u't0.address_name'}]
+ resultSet = connection.query(content, None, sortOrder)
+ recList = []
+ recData = []
- def __rsToSeq (self, rs, fields, reorder = False):
- """
- Flatten a resultSet into a sequence of tuples holding the requested field
- values.
+ for rec in resultSet:
+ country = rec.getField(u'address_country')
+ if country is not None:
+ jRec = connection.findRecord(u'address_country', country, [])
+ cCode = jRec.getField(u'address_code')
+ else:
+ cCode = None
- @param rs: the resultset to iterate
- @param fields: sequence of fieldnames to extract
- @param reorder: if True, the resulting sequence will be sorted
+ recData.append((rec.getField(u'address_name'), cCode))
- @return: sequence of value-tuples, one per record. If only one field is
- requested, the result is a sequence of field-values (without tuples)
- """
+ recList.append(rec)
- result = []
- append = len (fields) == 1 and result.extend or result.append
+ resultSet.close()
- for rec in rs:
- append ([rec.getField (f) for f in fields])
+ return (recList, recData)
- rs.close ()
- if reorder:
- result.sort ()
+ # -------------------------------------------------------------------------
+ # Convert a resultSet into a flat sequence
+ # -------------------------------------------------------------------------
- return result
+ def __rsToSeq(self, rs, fields, reorder = False):
+ """
+ Flatten a resultSet into a sequence of tuples holding the requested
+ field values.
+ @param rs: the resultset to iterate
+ @param fields: sequence of fieldnames to extract
+ @param reorder: if True, the resulting sequence will be sorted
+ @return: sequence of value-tuples, one per record. If only one field is
+ requested, the result is a sequence of field-values (without
tuples)
+ """
+
+ result = []
+ append = len(fields) == 1 and result.extend or result.append
+
+ for rec in rs:
+ append([rec.getField(f) for f in fields])
+
+ rs.close()
+
+ if reorder:
+ result.sort()
+
+ return result
+
+
# =============================================================================
# Main program
# =============================================================================
if __name__ == '__main__':
- suite1 = unittest.makeSuite (CachingTestCase)
- suite2 = unittest.makeSuite (ConnectionTestCase)
- alltests = unittest.TestSuite ((suite1, suite2))
+ suite1 = unittest.makeSuite(CachingTestCase)
+ suite2 = unittest.makeSuite(ConnectionTestCase)
+ alltests = unittest.TestSuite((suite1, suite2))
- unittest.TextTestRunner (verbosity = 2).run (alltests)
+ unittest.TextTestRunner(verbosity = 2).run(alltests)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r9784 - in trunk/gnue-appserver: src tests,
johannes <=