[Zodb-checkins] CVS: StandaloneZODB/ZEO/tests - testZEO.py:1.1.2.18

Jeremy Hylton jeremy@zope.com
Tue, 8 Jan 2002 23:47:39 -0500


Update of /cvs-repository/StandaloneZODB/ZEO/tests
In directory cvs.zope.org:/tmp/cvs-serv4985

Modified Files:
      Tag: ZEO-ZRPC-Dev
	testZEO.py 
Log Message:
Add two tests of new zrpc2 multiple addresses feature.

The tests are a bit kludgey and make the start/shutdownServer()
machinery more complicated -- perhaps too complex.  But I'm not yet
sure what the right refactoring is/would be.

The checkMultipleServers() test could be better, but it works without
depending on Standby.  It just does a dostore() at two different
servers using a single ClientStorage.


=== StandaloneZODB/ZEO/tests/testZEO.py 1.1.2.17 => 1.1.2.18 ===
         self.running = 1
         client, exit, pid = forker.start_zeo(self.getStorage())
-        self._pid = pid
-        self._server = exit
+        self._pids = [pid]
+        self._servers = [exit]
         self._storage = PackWaitWrapper(client)
         client.registerDB(DummyDB(), None)
         self.__super_setUp()
@@ -168,8 +168,10 @@
         """Try to cause the tests to halt"""
         self.running = 0
         self._storage.close()
-        self._server.close()
-        os.waitpid(self._pid, 0)
+        for server in self._servers:
+            server.close()
+        for pid in self._pids:
+            os.waitpid(pid, 0)
         self.delStorage()
         self.__super_tearDown()
 
@@ -189,9 +191,10 @@
         # cleaner way.
         
         # Is this the only way to get the address?
-        addr = self._storage._rpc_mgr.addr
+        addr = self._storage._rpc_mgr.addr[0][1]
         self._storage.close()
-        self._storage = ZEO.ClientStorage.ClientStorage(addr, read_only=1)
+        self._storage = ZEO.ClientStorage.ClientStorage(addr, read_only=1,
+                                             wait_for_server_on_startup=1)
 
     def getStorage(self):
         return FileStorage(self.__fs_base, create=1)
@@ -277,24 +280,58 @@
 
     def tearDown(self):
         """Try to cause the tests to halt"""
+        if getattr(self, '_storage', None) is not None:
+            self._storage.close()
         self.shutdownServer()
         # file storage appears to create four files
-        for ext in '', '.index', '.lock', '.tmp':
-            path = self.file + ext
-            if os.path.exists(path):
-                os.unlink(path)
+        for i in range(len(self.addr)):
+            for ext in '', '.index', '.lock', '.tmp':
+                path = "%s.%s%s" % (self.file, i, ext)
+                if os.path.exists(path):
+                    os.unlink(path)
         for i in 0, 1:
             path = "c1-test-%d.zec" % i
             if os.path.exists(path):
                 os.unlink(path)
         self.__super_tearDown()
 
+    def checkMultipleAddresses(self):
+        for i in range(4):
+            self._newAddr()
+        self._storage = self.openClientStorage('test', 100000, wait=1)
+        oid = self._storage.new_oid()
+        obj = MinPO(12)
+        revid1 = self._dostore(oid, data=obj)
+        self._storage.close()
+
+    def checkMultipleServers(self):
+        # XXX crude test at first -- just start two servers and do a
+        # commit at each one.
+        
+        self._newAddr()
+        self._storage = self.openClientStorage('test', 100000, wait=1)
+        self._dostore()
+
+        self.shutdownServer(index=0)
+        self._startServer(index=1)
+        
+        # If we can still store after shutting down one of the
+        # servers, we must be reconnecting to the other server.
+
+        for i in range(10):
+            try:
+                self._dostore()
+                break
+            except Disconnected:
+                time.sleep(0.5)
+            
+
     def checkDisconnectionError(self):
         # Make sure we get a Disconnected when we try to read an
         # object when we're not connected to a storage server and the
         # object is not in the cache.
         self.shutdownServer()
-        self._storage = self.openClientStorage('test', 1000, 0)
+        self._storage = self.openClientStorage('test', 1000, wait=0)
         self.assertRaises(Disconnected, self._storage.load, 'fredwash', '')
 
     def checkBasicPersistence(self):
@@ -303,13 +340,13 @@
         # To verify that the cache is being used, the test closes the
         # server and then starts a new client with the server down.
 
-        self._storage = self.openClientStorage('test', 100000, 1)
+        self._storage = self.openClientStorage('test', 100000, wait=1)
         oid = self._storage.new_oid()
         obj = MinPO(12)
         revid1 = self._dostore(oid, data=obj)
         self._storage.close()
         self.shutdownServer()
-        self._storage = self.openClientStorage('test', 100000, 0)
+        self._storage = self.openClientStorage('test', 100000, wait=0)
         data, revid2 = self._storage.load(oid, '')
         assert zodb_unpickle(data) == MinPO(12)
         assert revid1 == revid2
@@ -321,7 +358,7 @@
         # In this case, only one object fits in a cache file.  When the
         # cache files swap, the first object is effectively uncached.
         
-        self._storage = self.openClientStorage('test', 1000, 1)
+        self._storage = self.openClientStorage('test', 1000, wait=1)
         oid1 = self._storage.new_oid()
         obj1 = MinPO("1" * 500)
         revid1 = self._dostore(oid1, data=obj1)
@@ -330,13 +367,20 @@
         revid2 = self._dostore(oid2, data=obj2)
         self._storage.close()
         self.shutdownServer()
-        self._storage = self.openClientStorage('test', 1000, 0)
+        self._storage = self.openClientStorage('test', 1000, wait=0)
         self._storage.load(oid1, '')
         self._storage.load(oid2, '')
 
     def checkReconnection(self):
         # Check that the client reconnects when a server restarts.
 
+        # XXX Seem to get occasional errors that look like this:
+        # File ZEO/zrpc2.py, line 217, in handle_request
+        # File ZEO/StorageServer.py, line 325, in storea
+        # File ZEO/StorageServer.py, line 209, in _check_tid
+        # StorageTransactionError: (None, <tid>)
+        # could system reconnect and continue old transaction?
+
         self._storage = self.openClientStorage()
         oid = self._storage.new_oid()
         obj = MinPO(12)
@@ -350,7 +394,8 @@
             try:
                 revid1 = self._dostore(oid, data=obj)
                 break
-            except (Disconnected, select.error, thread.error, socket.error), err:
+            except (Disconnected, select.error, thread.error, socket.error), \
+                   err:
                 get_transaction().abort()
                 time.sleep(0.1) # XXX how long to sleep
             # XXX This is a bloody pain.  We're placing a heavy burden
@@ -370,13 +415,25 @@
         """
         self.running = 1
         self.file = tempfile.mktemp()
-        self.addr = '', self.ports.pop()
+        self.addr = []
+        self._pids = []
+        self._servers = []
+        self._newAddr()
         self._startServer()
         self.__super_setUp()
 
-    def _startServer(self, create=1):
-        fs = FileStorage(self.file, create=create)
-        self._pid, self._server = forker.start_zeo_server(fs, self.addr)
+    def _newAddr(self):
+        self.addr.append(self._getAddr())
+
+    def _getAddr(self):
+        return '', self.ports.pop()
+
+    def _startServer(self, create=1, index=0):
+        fs = FileStorage("%s.%d" % (self.file, index), create=create)
+        addr = self.addr[index]
+        pid, server = forker.start_zeo_server(fs, addr)
+        self._pids.append(pid)
+        self._servers.append(server)
 
     def openClientStorage(self, cache='', cache_size=200000, wait=1):
         base = ZEO.ClientStorage.ClientStorage(self.addr,
@@ -388,18 +445,20 @@
         storage.registerDB(DummyDB(), None)
         return storage
 
-    def shutdownServer(self):
+    def shutdownServer(self, index=0):
         if self.running:
             self.running = 0
-            self._server.close()
+            self._servers[index].close()
             try:
-                os.waitpid(self._pid, 0)
+                os.waitpid(self._pids[index], 0)
             except os.error:
                 pass
 
 class WindowsConnectionTests(ConnectionTests):
     __super_setUp = StorageTestBase.StorageTestBase.setUp
 
+    # XXX these tests are now out-of-date
+
     def setUp(self):
         self.file = tempfile.mktemp()
         self._startServer()
@@ -451,7 +510,8 @@
     return meth.keys()
 
 if os.name == "posix":
-    test_classes = ZEOFileStorageTests, UnixConnectionTests
+##    test_classes = ZEOFileStorageTests, UnixConnectionTests
+    test_classes = UnixConnectionTests,
 elif os.name == "nt":
     test_classes = WindowsZEOFileStorageTests, WindowsConnectionTests
 else: