[Zope-Checkins] CVS: ZODB3/ZEO/tests - zeoserver.py:1.13.10.2 testZEO.py:1.66.2.2 testMonitor.py:1.3.12.2 testConnection.py:1.10.14.2 testAuth.py:1.1.2.7 forker.py:1.34.10.1 ConnectionTests.py:1.22.2.2

Jeremy Hylton jeremy@zope.com
Thu, 29 May 2003 17:30:40 -0400


Update of /cvs-repository/ZODB3/ZEO/tests
In directory cvs.zope.org:/tmp/cvs-serv26060/ZEO/tests

Modified Files:
      Tag: ZODB3-auth-branch
	zeoserver.py testZEO.py testMonitor.py testConnection.py 
	testAuth.py forker.py ConnectionTests.py 
Log Message:
Merge new test configuration changes from trunk.


=== ZODB3/ZEO/tests/zeoserver.py 1.13.10.1 => 1.13.10.2 ===
--- ZODB3/ZEO/tests/zeoserver.py:1.13.10.1	Thu May 29 12:27:54 2003
+++ ZODB3/ZEO/tests/zeoserver.py	Thu May 29 17:30:09 2003
@@ -26,8 +26,8 @@
 
 import ZConfig.Context
 import zLOG
-import ZEO.StorageServer
-from ZODB.config import storageFromURL
+from ZEO.StorageServer import StorageServer
+from ZEO.runzeo import ZEOOptions
 
 
 def cleanup(storage):
@@ -134,54 +134,56 @@
 def main():
     label = 'zeoserver:%d' % os.getpid()
     log(label, 'starting')
+    
     # We don't do much sanity checking of the arguments, since if we get it
     # wrong, it's a bug in the test suite.
-    ro_svr = 0
     keep = 0
     configfile = None
-    invalidation_queue_size = 100
-    transaction_timeout = None
-    monitor_address = None
     # Parse the arguments and let getopt.error percolate
-    opts, args = getopt.getopt(sys.argv[1:], 'rkC:Q:T:m:')
+    opts, args = getopt.getopt(sys.argv[1:], 'kC:')
     for opt, arg in opts:
-        if opt == '-r':
-            ro_svr = 1
-        elif opt == '-k':
+        if opt == '-k':
             keep = 1
         elif opt == '-C':
             configfile = arg
-        elif opt == '-Q':
-            invalidation_queue_size = int(arg)
-        elif opt == '-T':
-            transaction_timeout = int(arg)
-        elif opt == "-m":
-            monitor_address = '', int(arg)
+
+    zo = ZEOOptions()
+    zo.realize(["-C", configfile])
+    zeo_port = int(zo.address[1])
+            
+    # XXX a hack
+    if zo.auth_protocol == "plaintext":
+        import ZEO.tests.auth_plaintext
+        
     # Open the config file and let ZConfig parse the data there.  Then remove
     # the config file, otherwise we'll leave turds.
-    storage = storageFromURL(configfile)
-    os.remove(configfile)
     # The rest of the args are hostname, portnum
-    zeo_port = int(args[0])
     test_port = zeo_port + 1
     test_addr = ('localhost', test_port)
     addr = ('localhost', zeo_port)
     log(label, 'creating the storage server')
-    serv = ZEO.StorageServer.StorageServer(
-        addr, {'1': storage}, ro_svr,
-        invalidation_queue_size=invalidation_queue_size,
-        transaction_timeout=transaction_timeout,
-        monitor_address=monitor_address)
+    storage = zo.storages[0].open()
+    server = StorageServer(
+        zo.address,
+        {"1": storage},
+        read_only=zo.read_only,
+        invalidation_queue_size=zo.invalidation_queue_size,
+        transaction_timeout=zo.transaction_timeout,
+        monitor_address=zo.monitor_address,
+        auth_protocol=zo.auth_protocol,
+        auth_filename=zo.auth_database)
+    
     try:
-        log(label, 'creating the test server, ro: %s, keep: %s', ro_svr, keep)
-        t = ZEOTestServer(test_addr, serv, keep)
+        log(label, 'creating the test server, keep: %s', keep)
+        t = ZEOTestServer(test_addr, server, keep)
     except socket.error, e:
         if e[0] <> errno.EADDRINUSE: raise
         log(label, 'addr in use, closing and exiting')
         storage.close()
         cleanup(storage)
         sys.exit(2)
-    t.register_socket(serv.dispatcher)
+        
+    t.register_socket(server.dispatcher)
     # Create daemon suicide thread
     d = Suicide(test_addr)
     d.setDaemon(1)


=== ZODB3/ZEO/tests/testZEO.py 1.66.2.1 => 1.66.2.2 ===
--- ZODB3/ZEO/tests/testZEO.py:1.66.2.1	Thu May 29 12:27:54 2003
+++ ZODB3/ZEO/tests/testZEO.py	Thu May 29 17:30:09 2003
@@ -17,6 +17,7 @@
 import os
 import sys
 import time
+import random
 import socket
 import asyncore
 import tempfile
@@ -37,14 +38,8 @@
      PackableStorage, Synchronization, ConflictResolution, RevisionStorage, \
      MTStorage, ReadOnlyStorage
 
-# ZEO imports
 from ZEO.ClientStorage import ClientStorage
-
-# ZEO test support
-from ZEO.tests import forker, Cache
-
-# ZEO test mixin classes
-from ZEO.tests import CommitLockTests, ThreadTests
+from ZEO.tests import forker, Cache, CommitLockTests, ThreadTests
 
 class DummyDB:
     def invalidate(self, *args):
@@ -80,6 +75,47 @@
         finally:
             storage2.close()
 
+def get_port():
+    """Return a port that is not in use.
+
+    Checks if a port is in use by trying to connect to it.  Assumes it
+    is not in use if connect raises an exception.
+
+    Raises RuntimeError after 10 tries.
+    """
+    for i in range(10):
+        port = random.randrange(20000, 30000)
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        try:
+            try:
+                s.connect(('localhost', port))
+            except socket.error:
+                # XXX check value of error?
+                return port
+        finally:
+            s.close()
+    raise RuntimeError, "Can't find port"
+
+def get_port():
+    """Return a port that is not in use.
+
+    Checks if a port is in use by trying to connect to it.  Assumes it
+    is not in use if connect raises an exception.
+
+    Raises RuntimeError after 10 tries.
+    """
+    for i in range(10):
+        port = random.randrange(20000, 30000)
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        try:
+            try:
+                s.connect(('localhost', port))
+            except socket.error:
+                # XXX check value of error?
+                return port
+        finally:
+            s.close()
+    raise RuntimeError, "Can't find port"
 
 class GenericTests(
     # Base class for all ZODB tests
@@ -109,15 +145,20 @@
 
     def setUp(self):
         zLOG.LOG("testZEO", zLOG.INFO, "setUp() %s" % self.id())
-        zeoport, adminaddr, pid = forker.start_zeo_server(self.getConfig())
+        port = get_port()
+        zconf = forker.ZEOConfig(('', port))
+        zport, adminaddr, pid, path = forker.start_zeo_server(self.getConfig(),
+                                                              zconf, port)
         self._pids = [pid]
         self._servers = [adminaddr]
-        self._storage = ClientStorage(zeoport, '1', cache_size=20000000,
+        self._conf_path = path
+        self._storage = ClientStorage(zport, '1', cache_size=20000000,
                                       min_disconnect_poll=0.5, wait=1)
         self._storage.registerDB(DummyDB(), None)
 
     def tearDown(self):
         self._storage.close()
+        os.remove(self._conf_path)
         for server in self._servers:
             forker.shutdown_zeo_server(server)
         if hasattr(os, 'waitpid'):
@@ -150,7 +191,7 @@
     def getConfig(self):
         filename = self.__fs_base = tempfile.mktemp()
         return """\
-        <filestorage>
+        <filestorage 1>
         path %s
         </filestorage>
         """ % filename
@@ -162,7 +203,7 @@
     def getConfig(self):
         self._envdir = tempfile.mktemp()
         return """\
-        <fullstorage>
+        <fullstorage 1>
         name %s
         </fullstorage>
         """ % self._envdir
@@ -171,7 +212,7 @@
     """ZEO backed by a Mapping storage."""
 
     def getConfig(self):
-        return """<mappingstorage/>"""
+        return """<mappingstorage 1/>"""
 
     # Tests which MappingStorage can't possibly pass, because it doesn't
     # support versions or undo.


=== ZODB3/ZEO/tests/testMonitor.py 1.3.12.1 => 1.3.12.2 ===
--- ZODB3/ZEO/tests/testMonitor.py:1.3.12.1	Thu May 29 12:27:54 2003
+++ ZODB3/ZEO/tests/testMonitor.py	Thu May 29 17:30:09 2003
@@ -72,7 +72,7 @@
         return d
         
     def getConfig(self, path, create, read_only):
-        return """<mappingstorage/>"""
+        return """<mappingstorage 1/>"""
 
     def testMonitor(self):
         # just open a client to know that the server is up and running


=== ZODB3/ZEO/tests/testConnection.py 1.10.14.1 => 1.10.14.2 ===
--- ZODB3/ZEO/tests/testConnection.py:1.10.14.1	Thu May 29 12:27:54 2003
+++ ZODB3/ZEO/tests/testConnection.py	Thu May 29 17:30:09 2003
@@ -26,7 +26,7 @@
 class FileStorageConfig:
     def getConfig(self, path, create, read_only):
         return """\
-        <filestorage>
+        <filestorage 1>
         path %s
         create %s
         read-only %s
@@ -37,14 +37,14 @@
 class BerkeleyStorageConfig:
     def getConfig(self, path, create, read_only):
         return """\
-        <fullstorage>
+        <fullstorage 1>
         name %s
         read-only %s
         </fullstorage>""" % (path, read_only and "yes" or "no")
 
 class MappingStorageConfig:
     def getConfig(self, path, create, read_only):
-        return """<mappingstorage/>"""
+        return """<mappingstorage 1/>"""
 
 
 class FileStorageConnectionTests(


=== ZODB3/ZEO/tests/testAuth.py 1.1.2.6 => 1.1.2.7 ===
--- ZODB3/ZEO/tests/testAuth.py:1.1.2.6	Thu May 29 12:27:54 2003
+++ ZODB3/ZEO/tests/testAuth.py	Thu May 29 17:30:09 2003
@@ -14,60 +14,55 @@
 """Test suite for AuthZEO."""
 
 import os
+import tempfile
 import time
 import unittest
 
 from ThreadedAsync import LoopCallback
 from ZEO.ClientStorage import ClientStorage
 from ZEO.StorageServer import StorageServer
+from ZEO.tests.ConnectionTests import CommonSetupTearDown
+
 from ZODB.FileStorage import FileStorage
 from ZODB.tests.StorageTestBase import removefs
 
-storage = FileStorage('auth-test.fs')
-
-SOCKET='auth-test-socket'
-STORAGES={'1': storage}
-
-class BaseTest(unittest.TestCase):
-
-    realm = None
+class AuthTest(CommonSetupTearDown):
+    __super_getServerConfig = CommonSetupTearDown.getServerConfig
+    __super_setUp = CommonSetupTearDown.setUp
+    __super_tearDown = CommonSetupTearDown.tearDown
     
-    def createDB(self, name):
-        if os.path.exists(SOCKET):
-            os.remove(SOCKET)
-        if os.path.exists(name):
-            os.remove(self.database)
+    realm = None
+
+    def setUp(self):
+        self.pwfile = tempfile.mktemp()
         if self.realm:
-            db = self.dbclass(name, self.realm)
+            self.pwdb = self.dbclass(self.pwfile, self.realm)
         else:
-            db = self.dbclass(name)
-        db.add_user("foo", "bar")
-        db.save()
-        
-    def setUp(self):
-        self.createDB(self.database)
-        # XXX needs to be fixed to work on Windows
-        self.pid = os.fork()
-        if not self.pid:
-            self.server = StorageServer(SOCKET, STORAGES,
-                                        auth_protocol=self.protocol,
-                                        auth_filename=self.database)
-            LoopCallback.loop()
-            sys.exit(0)
+            self.pwdb = self.dbclass(self.pwfile)
+        self.pwdb.add_user("foo", "bar")
+        self.pwdb.save()
+        self.__super_setUp()
 
     def tearDown(self):
-        os.kill(self.pid, 9)
-        os.waitpid(self.pid, 0)
-        os.remove(self.database)
-        os.remove(SOCKET)
-        removefs("auth-test.fs")
-        
+        self.__super_tearDown()
+        os.remove(self.pwfile)
+
+    def getConfig(self, path, create, read_only):
+        return "<mappingstorage 1/>"
+
+    def getServerConfig(self, addr, ro_svr):
+        zconf = self.__super_getServerConfig(addr, ro_svr)
+        zconf.authentication_protocol = self.protocol
+        zconf.authentication_database = self.pwfile
+        zconf.authentication_realm = self.realm
+        return zconf
+
     def testOK(self):
         # Sleep for 0.2 seconds to give the server some time to start up
         # seems to be needed before and after creating the storage
         time.sleep(self.wait)
-        cs = ClientStorage(SOCKET, wait=0, username='foo', password='bar',
-                           realm=self.realm)
+        cs = self.openClientStorage(wait=0, username="foo", password="bar",
+                                    realm=self.realm)
         try:
             time.sleep(self.wait)
 
@@ -88,8 +83,8 @@
     
     def testNOK(self):
         time.sleep(self.wait)
-        cs = ClientStorage(SOCKET, wait=0, username='foo', password='noogie',
-                           realm=self.realm)
+        cs = self.openClientStorage(wait=0, username="foo", password="noogie",
+                                    realm=self.realm)
         time.sleep(self.wait)
        
         # Normally a wrong password will return None immediately. 
@@ -103,21 +98,22 @@
     
         if cs.is_connected():
              raise AssertionError, "authenticated with incorrect password"
-            
-class PlainTextAuth(BaseTest):
+
+class PlainTextAuth(AuthTest):
     import ZEO.tests.auth_plaintext
     protocol = 'plaintext'
     database = 'authdb.sha'
     dbclass = ZEO.tests.auth_plaintext.Database
     wait = 0.2
+
     
-##class SRPAuth(BaseTest):
+##class SRPAuth(AuthTest):
 ##    protocol = 'srp'
 ##    database = 'authdb.srp'
 ##    dbclass = SRPDatabase
 ##    wait = 1.0
 
-class DigestAuth(BaseTest):
+class DigestAuth(AuthTest):
     import ZEO.auth.auth_digest
     protocol = "digest"
     database = "authdb.digest"


=== ZODB3/ZEO/tests/forker.py 1.34 => 1.34.10.1 ===
--- ZODB3/ZEO/tests/forker.py:1.34	Tue Mar  4 14:56:28 2003
+++ ZODB3/ZEO/tests/forker.py	Thu May 29 17:30:09 2003
@@ -19,77 +19,80 @@
 import errno
 import random
 import socket
+import StringIO
 import tempfile
 
 import zLOG
 
-# Change value of PROFILE to enable server-side profiling
-PROFILE = 0
-if PROFILE:
-    import hotshot
+class ZEOConfig:
+    """Class to generate ZEO configuration file. """
 
+    def __init__(self, addr):
+        self.address = addr
+        self.read_only = None
+        self.invalidation_queue_size = None
+        self.monitor_address = None
+        self.transaction_timeout = None
+        self.authentication_protocol = None
+        self.authentication_database = None
+        self.authentication_realm = None
+
+    def dump(self, f):
+        print >> f, "<zeo>"
+        print >> f, "address %s:%s" % self.address
+        if self.read_only is not None:
+            print >> f, "read-only", self.read_only and "true" or "false"
+        if self.invalidation_queue_size is not None:
+            print >> f, "invalidation-queue-size", self.invalidation_queue_size
+        if self.monitor_address is not None:
+            print >> f, "monitor-address %s:%s" % self.monitor_address
+        if self.transaction_timeout is not None:
+            print >> f, "transaction-timeout", self.transaction_timeout
+        if self.authentication_protocol is not None:
+            print >> f, "authentication-protocol", self.authentication_protocol
+        if self.authentication_database is not None:
+            print >> f, "authentication-database", self.authentication_database
+        if self.authentication_realm is not None:
+            print >> f, "authentication-realm", self.authentication_realm
+        print >> f, "</zeo>"
+
+    def __str__(self):
+        f = StringIO.StringIO()
+        self.dump(f)
+        return f.getvalue()
 
-def get_port():
-    """Return a port that is not in use.
-
-    Checks if a port is in use by trying to connect to it.  Assumes it
-    is not in use if connect raises an exception.
-
-    Raises RuntimeError after 10 tries.
-    """
-    for i in range(10):
-        port = random.randrange(20000, 30000)
-        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        try:
-            try:
-                s.connect(('localhost', port))
-            except socket.error:
-                # XXX check value of error?
-                return port
-        finally:
-            s.close()
-    raise RuntimeError, "Can't find port"
-
-
-def start_zeo_server(conf, addr=None, ro_svr=0, monitor=0, keep=0, invq=None,
-                     timeout=None):
+def start_zeo_server(storage_conf, zeo_conf, port, keep=0):
     """Start a ZEO server in a separate process.
 
-    Returns the ZEO port, the test server port, and the pid.
+    Takes two positional arguments a string containing the storage conf
+    and a ZEOConfig object.
+
+    Returns the ZEO port, the test server port, the pid, and the path
+    to the config file.
     """
+    
     # Store the config info in a temp file.
-    tmpfile = tempfile.mktemp()
+    tmpfile = tempfile.mktemp(".conf")
     fp = open(tmpfile, 'w')
-    fp.write(conf)
+    zeo_conf.dump(fp)
+    fp.write(storage_conf)
     fp.close()
-    # Create the server
+    
+    # Find the zeoserver script
     import ZEO.tests.zeoserver
-    if addr is None:
-        port = get_port()
-    else:
-        port = addr[1]
     script = ZEO.tests.zeoserver.__file__
     if script.endswith('.pyc'):
         script = script[:-1]
+        
     # Create a list of arguments, which we'll tuplify below
     qa = _quote_arg
     args = [qa(sys.executable), qa(script), '-C', qa(tmpfile)]
-    if ro_svr:
-        args.append('-r')
     if keep:
-        args.append('-k')
-    if invq:
-        args += ['-Q', str(invq)]
-    if timeout:
-        args += ['-T', str(timeout)]
-    if monitor:
-        # XXX Is it safe to reuse the port?
-        args += ['-m', '42000']
-    args.append(str(port))
+        args.append("-k")
     d = os.environ.copy()
     d['PYTHONPATH'] = os.pathsep.join(sys.path)
     pid = os.spawnve(os.P_NOWAIT, sys.executable, tuple(args), d)
-    adminaddr = ('localhost', port+1)
+    adminaddr = ('localhost', port + 1)
     # We need to wait until the server starts, but not forever
     for i in range(20):
         time.sleep(0.25)
@@ -108,7 +111,7 @@
     else:
         zLOG.LOG('forker', zLOG.DEBUG, 'boo hoo')
         raise
-    return ('localhost', port), adminaddr, pid
+    return ('localhost', port), adminaddr, pid, tmpfile
 
 
 if sys.platform[:3].lower() == "win":


=== ZODB3/ZEO/tests/ConnectionTests.py 1.22.2.1 => 1.22.2.2 ===
--- ZODB3/ZEO/tests/ConnectionTests.py:1.22.2.1	Thu May 29 12:27:54 2003
+++ ZODB3/ZEO/tests/ConnectionTests.py	Thu May 29 17:30:09 2003
@@ -77,12 +77,15 @@
         self.addr = []
         self._pids = []
         self._servers = []
+        self.conf_path = None
         self._newAddr()
         self.startServer()
 
     def tearDown(self):
         """Try to cause the tests to halt"""
         zLOG.LOG("testZEO", zLOG.INFO, "tearDown() %s" % self.id())
+        if self.conf_path:
+            os.remove(self.conf_path)
         if getattr(self, '_storage', None) is not None:
             self._storage.close()
             if hasattr(self._storage, 'cleanup'):
@@ -110,32 +113,50 @@
         # port+1 is also used, so only draw even port numbers
         return 'localhost', random.randrange(25000, 30000, 2)
 
-    def getConfig(self):
+    def getConfig(self, path, create, read_only):
         raise NotImplementedError
 
     def openClientStorage(self, cache='', cache_size=200000, wait=1,
-                          read_only=0, read_only_fallback=0):
+                          read_only=0, read_only_fallback=0,
+                          username=None, password=None, realm=None):
         base = TestClientStorage(self.addr,
                                  client=cache,
                                  cache_size=cache_size,
                                  wait=wait,
                                  min_disconnect_poll=0.1,
                                  read_only=read_only,
-                                 read_only_fallback=read_only_fallback)
+                                 read_only_fallback=read_only_fallback,
+                                 username=username,
+                                 password=password,
+                                 realm=realm)
         storage = base
         storage.registerDB(DummyDB(), None)
         return storage
 
+    def getServerConfig(self, addr, ro_svr):
+        zconf = forker.ZEOConfig(addr)
+        if ro_svr:
+            zconf.read_only = 1
+        if self.monitor:
+             zconf.monitor_address = ("", 42000)
+        if self.invq:
+            zconf.invalidation_queue_size = self.invq
+        if self.timeout:
+            zconf.transaction_timeout = self.timeout
+        return zconf
+
     def startServer(self, create=1, index=0, read_only=0, ro_svr=0):
         addr = self.addr[index]
         zLOG.LOG("testZEO", zLOG.INFO,
                  "startServer(create=%d, index=%d, read_only=%d) @ %s" %
                  (create, index, read_only, addr))
         path = "%s.%d" % (self.file, index)
-        conf = self.getConfig(path, create, read_only)
-        zeoport, adminaddr, pid = forker.start_zeo_server(
-            conf, addr, ro_svr,
-            self.monitor, self.keep, self.invq, self.timeout)
+        sconf = self.getConfig(path, create, read_only)
+        zconf = self.getServerConfig(addr, ro_svr)
+        zeoport, adminaddr, pid, path = forker.start_zeo_server(sconf, zconf,
+                                                                addr[1],
+                                                                self.keep)
+        self.conf_path = path
         self._pids.append(pid)
         self._servers.append(adminaddr)
 
@@ -435,7 +456,6 @@
 
         self._storage = self.openClientStorage()
         self._dostore()
-
         
     # Test case for multiple storages participating in a single
     # transaction.  This is not really a connection test, but it needs