[Neo-report] r2817 jm - in /trunk/neo: master/ tests/functional/ tests/threaded/

nobody at svn.erp5.org nobody at svn.erp5.org
Sat Sep 3 17:44:30 CEST 2011


Author: jm
Date: Sat Sep  3 17:44:29 2011
New Revision: 2817

Log:
Split testVerificationCommitUnfinishedTransactions into 1 passing and 1 failing tests

testVerificationCommitUnfinishedTransactions was failing randomly depending
on whether the cluster was started before or after the storage initializing
connection with the master.

Modified:
    trunk/neo/master/recovery.py
    trunk/neo/tests/functional/__init__.py
    trunk/neo/tests/functional/testCluster.py
    trunk/neo/tests/threaded/__init__.py
    trunk/neo/tests/threaded/test.py

Modified: trunk/neo/master/recovery.py
==============================================================================
--- trunk/neo/master/recovery.py [iso-8859-1] (original)
+++ trunk/neo/master/recovery.py [iso-8859-1] Sat Sep  3 17:44:29 2011
@@ -42,6 +42,10 @@ class RecoveryManager(MasterHandler):
         """
             Returns the handler for storage nodes
         """
+        # XXX: Looking at 'uuid' is not a good criteria to know if the storage
+        #      is empty. Empty node should be accepted here.
+        #      This is also the first step to fix handling of incoming
+        #      non-empty storage nodes, whereas startup was already allowed.
         if uuid is None and not self.app._startup_allowed:
             neo.lib.logging.info('reject empty storage node')
             raise NotReadyError

Modified: trunk/neo/tests/functional/__init__.py
==============================================================================
--- trunk/neo/tests/functional/__init__.py [iso-8859-1] (original)
+++ trunk/neo/tests/functional/__init__.py [iso-8859-1] Sat Sep  3 17:44:29 2011
@@ -347,18 +347,6 @@ class NEOCluster(object):
             sql_connection.commit()
             sql_connection.close()
 
-    def switchTables(self, database):
-        sql_connection = self.__getSuperSQLConnection()
-        cursor = sql_connection.cursor()
-        cursor.execute('use %s' % (database, ))
-        for table in ('trans', 'obj'):
-            cursor.execute('rename table %s to tmp' % (table, ))
-            cursor.execute('rename table t%s to %s' % (table, table))
-            cursor.execute('rename table tmp to t%s' % (table, ))
-        cursor.execute('truncate table obj_short')
-        sql_connection.commit()
-        sql_connection.close()
-
     def run(self, except_storages=()):
         """ Start cluster processes except some storage nodes """
         assert len(self.process_dict)

Modified: trunk/neo/tests/functional/testCluster.py
==============================================================================
--- trunk/neo/tests/functional/testCluster.py [iso-8859-1] (original)
+++ trunk/neo/tests/functional/testCluster.py [iso-8859-1] Sat Sep  3 17:44:29 2011
@@ -78,26 +78,6 @@ class ClusterTests(NEOFunctionalTest):
         self.neo.expectAllMasters(MASTER_COUNT)
         self.neo.expectOudatedCells(0)
 
-    def testVerificationCommitUnfinishedTransactions(self):
-        """ Verification step should commit unfinished transactions """
-        # XXX: this kind of definition should be defined in base test class
-        class PObject(Persistent):
-            pass
-        self.neo = NEOCluster(['test_neo1'], replicas=0,
-            temp_dir=self.getTempDirectory(), adapter='MySQL')
-        neoctl = self.neo.getNEOCTL()
-        self.neo.start()
-        db, conn = self.neo.getZODBConnection()
-        conn.root()[0] = 'ok'
-        transaction.commit()
-        self.neo.stop(clients=False)
-        # XXX: (obj|trans) become t(obj|trans)
-        self.neo.switchTables('test_neo1')
-        self.neo.start()
-        db, conn = self.neo.getZODBConnection()
-        # transaction should be verified and commited
-        self.assertEqual(conn.root()[0], 'ok')
-
     def testLeavingOperationalStateDropClientNodes(self):
         """
             Check that client nodes are dropped where the cluster leaves the

Modified: trunk/neo/tests/threaded/__init__.py
==============================================================================
--- trunk/neo/tests/threaded/__init__.py [iso-8859-1] (original)
+++ trunk/neo/tests/threaded/__init__.py [iso-8859-1] Sat Sep  3 17:44:29 2011
@@ -235,6 +235,24 @@ class StorageApplication(ServerNode, neo
         except StandardError: # AttributeError & ProgrammingError
             pass
 
+    def switchTables(self):
+        adapter = self._init_args[1]['getAdapter']
+        dm = self.dm
+        if adapter == 'BTree':
+            dm._obj, dm._tobj = dm._tobj, dm._obj
+            dm._trans, dm._ttrans = dm._ttrans, dm._trans
+        elif adapter == 'MySQL':
+            q = dm.query
+            dm.begin()
+            for table in ('trans', 'obj'):
+                q('RENAME TABLE %s to tmp' % table)
+                q('RENAME TABLE t%s to %s' % (table, table))
+                q('RENAME TABLE tmp to t%s' % table)
+            q('TRUNCATE obj_short')
+            dm.commit()
+        else:
+            assert False
+
 class ClientApplication(neo.client.app.Application):
 
     @SerializedEventManager.decorate
@@ -434,7 +452,7 @@ class NEOCluster(object):
             return db
 
     def stop(self):
-        getattr(self, '_db', self.client).close()
+        self.__dict__.pop('_db', self.client).close()
         #self.neoctl.setClusterState(ClusterStates.STOPPING) # TODO
         try:
             Serialized.release(stop=1)

Modified: trunk/neo/tests/threaded/test.py
==============================================================================
--- trunk/neo/tests/threaded/test.py [iso-8859-1] (original)
+++ trunk/neo/tests/threaded/test.py [iso-8859-1] Sat Sep  3 17:44:29 2011
@@ -116,3 +116,35 @@ class Test(NEOThreadedTest):
 
     def testRestartWithMissingStorageFastStartup(self):
         self.testRestartWithMissingStorage(True)
+
+    def testVerificationCommitUnfinishedTransactions(self, fast_startup=False):
+        # translated from neo.tests.functional.testCluster.ClusterTests
+        """ Verification step should commit unfinished transactions """
+        # XXX: this kind of definition should be defined in base test class
+        cluster = NEOCluster()
+        try:
+            cluster.start()
+            t, c = cluster.getTransaction()
+            c.root()[0] = 'ok'
+            t.commit()
+        finally:
+            cluster.stop()
+        cluster.reset()
+        # XXX: (obj|trans) become t(obj|trans)
+        cluster.storage.switchTables()
+        try:
+            cluster.start(fast_startup=fast_startup)
+            t, c = cluster.getTransaction()
+            # transaction should be verified and commited
+            self.assertEqual(c.root()[0], 'ok')
+        finally:
+            cluster.stop()
+
+    def testVerificationCommitUnfinishedTransactionsFastStartup(self):
+        # XXX: This test fails because if the admin starts the cluster without
+        #      any storage node, the master (which is still in recovery stage)
+        #      does not handle properly incoming non-empty storage nodes.
+        #      In particular, it does not ask the last ids to the storage,
+        #      and the client will ask objects at tid 0.
+        #      See also RecoveryManager.identifyStorageNode
+        self.testVerificationCommitUnfinishedTransactions(True)




More information about the Neo-report mailing list