[Zope3-checkins] CVS: ZODB4/src/zodb/zeo/tests - invalid.py:1.1.2.1 zeoserver.py:1.8.30.1 test_zeo.py:1.12.6.1 test_conn.py:1.5.6.1 forker.py:1.5.30.1
Jeremy Hylton
jeremy@zope.com
Tue, 17 Jun 2003 17:59:55 -0400
Update of /cvs-repository/ZODB4/src/zodb/zeo/tests
In directory cvs.zope.org:/tmp/cvs-serv10995/src/zodb/zeo/tests
Modified Files:
Tag: ZODB3-2-merge
zeoserver.py test_zeo.py test_conn.py forker.py
Added Files:
Tag: ZODB3-2-merge
invalid.py
Log Message:
Checkpoint progress merging ZODB 3.2 features and fixes into ZODB4.
=== Added File ZODB4/src/zodb/zeo/tests/invalid.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
from thread import get_ident
import threading
import time
from zodb.btrees.check import check, display
from zodb.btrees.OOBTree import OOBTree
from zodb.db import DB
from zodb.interfaces import ReadConflictError, ConflictError, VersionLockError
from zodb.zeo.tests.thread import TestThread
from zodb.zeo.tests.connection import CommonSetupTearDown
import logging
# XXX stopped porting here
# The tests here let several threads have a go at one or more database
# instances simultaneously. Each thread appends a disjoint (from the
# other threads) sequence of increasing integers to an OOBTree, one at
# at time (per thread). This provokes lots of conflicts, and BTrees
# work hard at conflict resolution too. An OOBTree is used because
# that flavor has the smallest maximum bucket size, and so splits buckets
# more often than other BTree flavors.
#
# When these tests were first written, they provoked an amazing number
# of obscure timing-related bugs in cache consistency logic, revealed
# by failure of the BTree to pass internal consistency checks at the end,
# and/or by failure of the BTree to contain all the keys the threads
# thought they added (i.e., the keys for which get_transaction().commit()
# did not raise any exception).
class StressThread(TestThread):
# Append integers startnum, startnum + step, startnum + 2*step, ...
# to 'tree' until Event stop is set. If sleep is given, sleep
# that long after each append. At the end, instance var .added_keys
# is a list of the ints the thread believes it added successfully.
def __init__(self, testcase, db, stop, threadnum, startnum,
step=2, sleep=None):
TestThread.__init__(self, testcase)
self.db = db
self.stop = stop
self.threadnum = threadnum
self.startnum = startnum
self.step = step
self.sleep = sleep
self.added_keys = []
def testrun(self):
cn = self.db.open()
while not self.stop.isSet():
try:
tree = cn.root()["tree"]
break
except (ConflictError, KeyError):
get_transaction().abort()
cn.sync()
key = self.startnum
while not self.stop.isSet():
try:
tree[key] = self.threadnum
get_transaction().note("add key %s" % key)
get_transaction().commit()
if self.sleep:
time.sleep(self.sleep)
except (ReadConflictError, ConflictError), msg:
get_transaction().abort()
# sync() is necessary here to process invalidations
# if we get a read conflict. In the read conflict case,
# no objects were modified so cn never got registered
# with the transaction.
cn.sync()
else:
self.added_keys.append(key)
key += self.step
cn.close()
class VersionStressThread(TestThread):
def __init__(self, testcase, db, stop, threadnum, startnum,
step=2, sleep=None):
TestThread.__init__(self, testcase)
self.db = db
self.stop = stop
self.threadnum = threadnum
self.startnum = startnum
self.step = step
self.sleep = sleep
self.added_keys = []
def log(self, msg):
zLOG.LOG("thread %d" % get_ident(), 0, msg)
def testrun(self):
self.log("thread begin")
commit = 0
key = self.startnum
while not self.stop.isSet():
version = "%s:%s" % (self.threadnum, key)
commit = not commit
self.log("attempt to add key=%s version=%s commit=%d" %
(key, version, commit))
if self.oneupdate(version, key, commit):
self.added_keys.append(key)
key += self.step
def oneupdate(self, version, key, commit=1):
# The mess of sleeps below were added to reduce the number
# of VersionLockErrors, based on empirical observation.
# It looks like the threads don't switch enough without
# the sleeps.
cn = self.db.open(version)
while not self.stop.isSet():
try:
tree = cn.root()["tree"]
break
except (ConflictError, KeyError):
get_transaction().abort()
cn.sync()
while not self.stop.isSet():
try:
tree[key] = self.threadnum
get_transaction().note("add key %d" % key)
get_transaction().commit()
if self.sleep:
time.sleep(self.sleep)
break
except (VersionLockError, ReadConflictError, ConflictError), msg:
self.log(msg)
get_transaction().abort()
# sync() is necessary here to process invalidations
# if we get a read conflict. In the read conflict case,
# no objects were modified so cn never got registered
# with the transaction.
cn.sync()
if self.sleep:
time.sleep(self.sleep)
try:
while not self.stop.isSet():
try:
if commit:
self.db.commitVersion(version)
get_transaction().note("commit version %s" % version)
else:
self.db.abortVersion(version)
get_transaction().note("abort version %s" % version)
get_transaction().commit()
if self.sleep:
time.sleep(self.sleep)
return commit
except ConflictError, msg:
self.log(msg)
get_transaction().abort()
cn.sync()
finally:
cn.close()
return 0
class InvalidationTests(CommonSetupTearDown):
level = 2
DELAY = 15 # number of seconds the main thread lets the workers run
def _check_tree(self, cn, tree):
# Make sure the BTree is sane and that all the updates persisted.
retries = 3
while retries:
retries -= 1
try:
check(tree)
tree._check()
except ReadConflictError:
if retries:
get_transaction().abort()
cn.sync()
else:
raise
except:
display(tree)
raise
def _check_threads(self, tree, *threads):
# Make sure the thread's view of the world is consistent with
# the actual database state.
all_keys = []
for t in threads:
# If the test didn't add any keys, it didn't do what we expected.
self.assert_(t.added_keys)
for key in t.added_keys:
self.assert_(tree.has_key(key), key)
all_keys.extend(t.added_keys)
all_keys.sort()
self.assertEqual(all_keys, list(tree.keys()))
def go(self, stop, *threads):
# Run the threads
for t in threads:
t.start()
time.sleep(self.DELAY)
stop.set()
for t in threads:
t.cleanup()
def testConcurrentUpdates2Storages(self):
self._storage = storage1 = self.openClientStorage()
storage2 = self.openClientStorage(cache="2")
db1 = DB(storage1)
db2 = DB(storage2)
stop = threading.Event()
cn = db1.open()
tree = cn.root()["tree"] = OOBTree()
get_transaction().commit()
# Run two threads that update the BTree
t1 = StressThread(self, db1, stop, 1, 1)
t2 = StressThread(self, db2, stop, 2, 2)
self.go(stop, t1, t2)
cn.sync()
self._check_tree(cn, tree)
self._check_threads(tree, t1, t2)
cn.close()
db1.close()
db2.close()
def testConcurrentUpdates1Storage(self):
self._storage = storage1 = self.openClientStorage()
db1 = DB(storage1)
stop = threading.Event()
cn = db1.open()
tree = cn.root()["tree"] = OOBTree()
get_transaction().commit()
# Run two threads that update the BTree
t1 = StressThread(self, db1, stop, 1, 1, sleep=0.001)
t2 = StressThread(self, db1, stop, 2, 2, sleep=0.001)
self.go(stop, t1, t2)
cn.sync()
self._check_tree(cn, tree)
self._check_threads(tree, t1, t2)
cn.close()
db1.close()
def testConcurrentUpdates2StoragesMT(self):
self._storage = storage1 = self.openClientStorage()
db1 = DB(storage1)
stop = threading.Event()
cn = db1.open()
tree = cn.root()["tree"] = OOBTree()
get_transaction().commit()
db2 = DB(self.openClientStorage(cache="2"))
# Run three threads that update the BTree.
# Two of the threads share a single storage so that it
# is possible for both threads to read the same object
# at the same time.
t1 = StressThread(self, db1, stop, 1, 1, 3)
t2 = StressThread(self, db2, stop, 2, 2, 3, 0.001)
t3 = StressThread(self, db2, stop, 3, 3, 3, 0.001)
self.go(stop, t1, t2, t3)
cn.sync()
self._check_tree(cn, tree)
self._check_threads(tree, t1, t2, t3)
cn.close()
db1.close()
db2.close()
def testConcurrentUpdatesInVersions(self):
self._storage = storage1 = self.openClientStorage()
db1 = DB(storage1)
db2 = DB(self.openClientStorage(cache="2"))
stop = threading.Event()
cn = db1.open()
tree = cn.root()["tree"] = OOBTree()
get_transaction().commit()
# Run three threads that update the BTree.
# Two of the threads share a single storage so that it
# is possible for both threads to read the same object
# at the same time.
t1 = VersionStressThread(self, db1, stop, 1, 1, 3)
t2 = VersionStressThread(self, db2, stop, 2, 2, 3, 0.001)
t3 = VersionStressThread(self, db2, stop, 3, 3, 3, 0.001)
self.go(stop, t1, t2, t3)
cn.sync()
self._check_tree(cn, tree)
self._check_threads(tree, t1, t2, t3)
cn.close()
db1.close()
db2.close()
=== ZODB4/src/zodb/zeo/tests/zeoserver.py 1.8 => 1.8.30.1 ===
--- ZODB4/src/zodb/zeo/tests/zeoserver.py:1.8 Tue Feb 25 13:55:05 2003
+++ ZODB4/src/zodb/zeo/tests/zeoserver.py Tue Jun 17 17:59:24 2003
@@ -28,12 +28,8 @@
from zodb import config
import zodb.zeo.server
from zodb.zeo import threadedasync
-
-def load_storage(fp):
- context = ZConfig.Context.Context()
- rootconf = context.loadFile(fp)
- storageconf = rootconf.getSection('Storage')
- return config.createStorage(storageconf)
+from zodb.zeo.runzeo import ZEOOptions
+from zodb.zeo.server import StorageServer
class ZEOTestServer(asyncore.dispatcher):
"""A server for killing the whole process at the end of a test.
@@ -123,56 +119,58 @@
# 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 = False
- keep = False
+ 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 = True
- elif opt == '-k':
- keep = True
+ 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.
- fp = open(configfile, 'r')
- storage = load_storage(fp)
- fp.close()
- os.remove(configfile)
# The rest of the args are hostname, portnum
- zeo_port = int(args[0])
test_port = zeo_port + 1
- test_addr = ('', test_port)
- addr = ('', zeo_port)
- serv = zodb.zeo.server.StorageServer(
- addr, {'1': storage}, ro_svr,
- invalidation_queue_size=invalidation_queue_size,
- transaction_timeout=transaction_timeout,
- monitor_address=monitor_address)
+ test_addr = ('localhost', test_port)
+ addr = ('localhost', zeo_port)
+ logger.info('creating the storage server')
+ storage = zo.storages[0].open()
+ mon_addr = None
+ if zo.monitor_address:
+ mon_addr = zo.monitor_address.address
+ 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=mon_addr,
+ auth_protocol=zo.auth_protocol,
+ auth_filename=zo.auth_database,
+ auth_realm=zo.auth_realm)
+
try:
- logger.info('creating the test server, ro: %s, keep: %s',
- ro_svr, keep)
- t = ZEOTestServer(test_addr, serv, keep)
+ logger.info('creating the test server, keep: %s', keep)
+ t = ZEOTestServer(test_addr, server, keep)
except socket.error, e:
if e[0] <> errno.EADDRINUSE: raise
logger.info('addr in use, closing and exiting')
storage.close()
- storage.cleanup()
+ cleanup(storage)
sys.exit(2)
- addr = ('', zeo_port)
+
logger.info('creating the storage server')
- t.register_socket(serv.dispatcher)
+ t.register_socket(server.dispatcher)
# Loop for socket events
logger.info('entering threadedasync loop')
threadedasync.loop()
=== ZODB4/src/zodb/zeo/tests/test_zeo.py 1.12 => 1.12.6.1 ===
--- ZODB4/src/zodb/zeo/tests/test_zeo.py:1.12 Fri May 16 18:53:47 2003
+++ ZODB4/src/zodb/zeo/tests/test_zeo.py Tue Jun 17 17:59:24 2003
@@ -19,6 +19,7 @@
import time
import errno
import socket
+import random
import logging
import asyncore
import tempfile
@@ -40,6 +41,27 @@
from zodb.zeo.tests import commitlock, threadtests
from zodb.zeo.tests.common import TestClientStorage, DummyDB
+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 DummyDB:
def invalidate(self, *args):
pass
@@ -102,8 +124,11 @@
logging.info("testZEO: setUp() %s", self.id())
config = self.getConfig()
for i in range(10):
+ port = get_port()
+ zconf = forker.ZEOConfig(('', port))
try:
- zeoport, adminaddr, pid = forker.start_zeo_server(config)
+ zport, adminaddr, pid, path = \
+ forker.start_zeo_server(config, zconf, port)
except socket.error, e:
if e[0] not in (errno.ECONNREFUSED, errno.ECONNRESET):
raise
@@ -113,14 +138,16 @@
raise
self._pids = [pid]
self._servers = [adminaddr]
- self._storage = TestClientStorage(zeoport, '1', cache_size=20000000,
- min_disconnect_poll=0.5, wait=1)
+ self._conf_path = path
+ self._storage = ClientStorage(zport, '1', cache_size=20000000,
+ min_disconnect_poll=0.5, wait=1)
self._storage.registerDB(DummyDB())
def tearDown(self):
# Clean up any transaction that might be left hanging around
get_transaction().abort()
self._storage.close()
+ os.remove(self._conf_path)
for server in self._servers:
forker.shutdown_zeo_server(server)
if hasattr(os, 'waitpid'):
@@ -174,11 +201,9 @@
def getConfig(self):
filename = self.__fs_base = tempfile.mktemp()
return """\
- <Storage>
- type FileStorage
- file_name %s
- create yes
- </Storage>
+ <filestorage 1>
+ path %s
+ </filestorage>
""" % filename
class BDBTests(UndoVersionStorageTests):
@@ -189,10 +214,9 @@
def getConfig(self):
self._envdir = tempfile.mktemp()
return """\
- <Storage>
- type BDBFullStorage
- name %s
- </Storage>
+ <fullstorage 1>
+ name %s
+ </fullstorage>
""" % self._envdir
# XXX These test seems to have massive failures when I run them.
@@ -207,19 +231,14 @@
class MappingStorageTests(StorageTests):
def getConfig(self):
- self._envdir = tempfile.mktemp()
- return """\
- <Storage>
- type MappingStorage
- name %s
- </Storage>
- """ % self._envdir
+ return """<mappingstorage 1/>"""
-test_classes = [FileStorageTests, MappingStorageTests]
+##test_classes = [FileStorageTests, MappingStorageTests]
-from zodb.storage.base import berkeley_is_available
-if berkeley_is_available:
- test_classes.append(BDBTests)
+##from zodb.storage.base import berkeley_is_available
+##if berkeley_is_available:
+## test_classes.append(BDBTests)
+test_classes = [BDBTests]
def test_suite():
suite = unittest.TestSuite()
=== ZODB4/src/zodb/zeo/tests/test_conn.py 1.5 => 1.5.6.1 ===
--- ZODB4/src/zodb/zeo/tests/test_conn.py:1.5 Fri May 16 17:49:36 2003
+++ ZODB4/src/zodb/zeo/tests/test_conn.py Tue Jun 17 17:59:24 2003
@@ -25,33 +25,25 @@
class FileStorageConfig:
def getConfig(self, path, create, read_only):
return """\
- <Storage>
- type FileStorage
- file_name %s
- create %s
- read_only %s
- </Storage>""" % (path,
- create and 'yes' or 'no',
- read_only and 'yes' or 'no')
+ <filestorage 1>
+ path %s
+ create %s
+ read-only %s
+ </filestorage>""" % (path,
+ create and 'yes' or 'no',
+ read_only and 'yes' or 'no')
class BerkeleyStorageConfig:
def getConfig(self, path, create, read_only):
- # Full always creates and doesn't have a read_only flag
return """\
- <Storage>
- type BDBFullStorage
- name %s
- read_only %s
- </Storage>""" % (path,
- read_only and 'yes' or 'no')
+ <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 """\
- <Storage>
- type MappingStorage
- name %s
- </Storage>""" % path
+ return """<mappingstorage 1/>"""
tests = [
(MappingStorageConfig, ConnectionTests, 1),
=== ZODB4/src/zodb/zeo/tests/forker.py 1.5 => 1.5.30.1 ===
--- ZODB4/src/zodb/zeo/tests/forker.py:1.5 Tue Feb 25 13:55:05 2003
+++ ZODB4/src/zodb/zeo/tests/forker.py Tue Jun 17 17:59:24 2003
@@ -16,104 +16,103 @@
import os
import sys
import time
+import logging
import errno
import random
import socket
+import StringIO
import tempfile
-import traceback
-import logging
-
-# Change value of PROFILE to enable server-side profiling
-PROFILE = False
-if PROFILE:
- import hotshot
-
-
-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 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 start_zeo_server(conf, addr=None, ro_svr=False, monitor=False, keep=False,
- 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 zodb.zeo.tests.zeoserver
- if addr is None:
- port = get_port()
- else:
- port = addr[1]
script = zodb.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)
- # We need to wait until the server starts, but not forever.
- # Always do a sleep as the first thing, since we don't expect
- # the spawned process to get started right away.
- delay = 0.25
- for i in range(10):
- time.sleep(delay)
- logging.debug('forker: connect %s', i)
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ adminaddr = ('localhost', port + 1)
+ logger = logging.getLogger("forker")
+ # We need to wait until the server starts, but not forever
+ for i in range(20):
+ time.sleep(0.25)
try:
+ logger.debug("connect %s", i)
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(adminaddr)
ack = s.recv(1024)
+ s.close()
+ logger.debug("acked: %s", ack)
+ break
except socket.error, e:
if e[0] not in (errno.ECONNREFUSED, errno.ECONNRESET):
raise
- logging.debug('forker: failed %s' % i)
s.close()
- else:
- logging.debug('forker: acked: %s', ack)
- s.close()
- break
else:
- logging.debug('forker: boo hoo')
+ logger.debug("boo foo")
raise
- return ('localhost', port), adminaddr, pid
+ return ('localhost', port), adminaddr, pid, tmpfile
+
if sys.platform[:3].lower() == "win":
def _quote_arg(s):
@@ -122,6 +121,7 @@
def _quote_arg(s):
return s
+
def shutdown_zeo_server(adminaddr):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(adminaddr)
@@ -130,5 +130,5 @@
except socket.error, e:
if e[0] <> errno.ECONNRESET: raise
ack = 'no ack received'
- logging.debug('shutdownServer: acked: %s', ack)
+ logging.getLogger("forker").debug("shutdown server acked: %s", ack)
s.close()