Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
966f7dfa
Commit
966f7dfa
authored
Jul 24, 2016
by
Hanno Schlichting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
flake8
parent
8e52f973
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
111 additions
and
108 deletions
+111
-108
src/Lifetime/__init__.py
src/Lifetime/__init__.py
+13
-10
src/Signals/SignalHandler.py
src/Signals/SignalHandler.py
+8
-4
src/Signals/Signals.py
src/Signals/Signals.py
+14
-9
src/Signals/WinSignalHandler.py
src/Signals/WinSignalHandler.py
+38
-34
src/Signals/__init__.py
src/Signals/__init__.py
+0
-3
src/Signals/threads.py
src/Signals/threads.py
+4
-4
src/Zope2/Startup/__init__.py
src/Zope2/Startup/__init__.py
+13
-16
src/Zope2/Startup/tests/testStarter.py
src/Zope2/Startup/tests/testStarter.py
+21
-28
No files found.
src/Lifetime/__init__.py
View file @
966f7dfa
import
sys
,
asyncore
,
time
import
asyncore
import
time
_shutdown_phase
=
0
_shutdown_timeout
=
30
# seconds per phase
_shutdown_timeout
=
30
# seconds per phase
# The shutdown phase counts up from 0 to 4.
#
...
...
@@ -23,7 +24,8 @@ _shutdown_timeout = 30 # seconds per phase
# of time that it has currently been in that phase. This method should return
# true if it does not yet want shutdown to proceed to the next phase.
def
shutdown
(
exit_code
,
fast
=
0
):
def
shutdown
(
exit_code
,
fast
=
0
):
global
_shutdown_phase
global
_shutdown_timeout
if
_shutdown_phase
==
0
:
...
...
@@ -38,6 +40,7 @@ def shutdown(exit_code,fast = 0):
# enough, but still clean.
_shutdown_timeout
=
1.0
def
loop
():
# Run the main loop until someone calls shutdown()
lifetime_loop
()
...
...
@@ -45,6 +48,7 @@ def loop():
# loop to allow remaining requests to trickle away.
graceful_shutdown_loop
()
def
lifetime_loop
():
# The main loop. Stay in here until we need to shutdown
map
=
asyncore
.
socket_map
...
...
@@ -52,7 +56,7 @@ def lifetime_loop():
while
map
and
_shutdown_phase
==
0
:
asyncore
.
poll
(
timeout
,
map
)
def
graceful_shutdown_loop
():
# The shutdown loop. Allow various services to shutdown gradually.
global
_shutdown_phase
...
...
@@ -60,19 +64,19 @@ def graceful_shutdown_loop():
timeout
=
1.0
map
=
asyncore
.
socket_map
while
map
and
_shutdown_phase
<
4
:
time_in_this_phase
=
time
.
time
()
-
timestamp
time_in_this_phase
=
time
.
time
()
-
timestamp
veto
=
0
for
fd
,
obj
in
map
.
items
():
for
fd
,
obj
in
map
.
items
():
try
:
fn
=
getattr
(
obj
,
'clean_shutdown_control'
)
fn
=
getattr
(
obj
,
'clean_shutdown_control'
)
except
AttributeError
:
pass
else
:
try
:
veto
=
veto
or
fn
(
_shutdown_phase
,
time_in_this_phase
)
veto
=
veto
or
fn
(
_shutdown_phase
,
time_in_this_phase
)
except
:
obj
.
handle_error
()
if
veto
and
time_in_this_phase
<
_shutdown_timeout
:
if
veto
and
time_in_this_phase
<
_shutdown_timeout
:
# Any open socket handler can veto moving on to the next shutdown
# phase. (but not forever)
asyncore
.
poll
(
timeout
,
map
)
...
...
@@ -80,4 +84,3 @@ def graceful_shutdown_loop():
# No vetos? That is one step closer to shutting down
_shutdown_phase
+=
1
timestamp
=
time
.
time
()
src/Signals/SignalHandler.py
View file @
966f7dfa
...
...
@@ -12,13 +12,15 @@
##############################################################################
"""Signal handling dispatcher."""
import
sys
,
os
import
os
import
sys
import
signal
from
logging
import
getLogger
LOG
=
getLogger
(
'SignalHandler'
)
LOG
=
getLogger
(
'SignalHandler'
)
class
SignalHandler
:
class
SignalHandler
(
object
):
def
__init__
(
self
):
self
.
registry
=
{}
...
...
@@ -52,7 +54,8 @@ class SignalHandler:
for
handler
in
self
.
registry
.
get
(
signum
,
[]):
# Never let a bad handler prevent the standard signal
# handlers from running.
try
:
handler
()
try
:
handler
()
except
SystemExit
:
# if we trap SystemExit, we can't restart
raise
...
...
@@ -62,6 +65,7 @@ class SignalHandler:
_signals
=
None
def
get_signal_name
(
n
):
"""Return the symbolic name for signal n.
...
...
src/Signals/Signals.py
View file @
966f7dfa
...
...
@@ -22,7 +22,6 @@ import Lifetime
from
.threads
import
dump_threads
logger
=
logging
.
getLogger
(
"Z2"
)
if
os
.
name
==
'nt'
:
...
...
@@ -37,11 +36,12 @@ if os.name == 'nt':
else
:
from
SignalHandler
import
SignalHandler
def
shutdownFastHandler
():
"""Shutdown cleanly on SIGTERM. This is registered first,
so it should be called after all other handlers."""
logger
.
info
(
"Shutting down fast"
)
Lifetime
.
shutdown
(
0
,
fast
=
1
)
Lifetime
.
shutdown
(
0
,
fast
=
1
)
def
shutdownHandler
():
...
...
@@ -50,6 +50,7 @@ def shutdownHandler():
logger
.
info
(
"Shutting down"
)
sys
.
exit
(
0
)
def
restartHandler
():
"""Restart cleanly on SIGHUP. This is registered first, so it
should be called after all other SIGHUP handlers."""
...
...
@@ -59,11 +60,11 @@ def restartHandler():
def
showStacks
():
"""Dump a stracktrace of all threads on the console."""
print
dump_threads
(
)
print
(
dump_threads
()
)
sys
.
stdout
.
flush
()
class
LogfileReopenHandler
:
class
LogfileReopenHandler
(
object
)
:
"""Reopen log files on SIGUSR2.
This is registered first, so it should be called after all other
...
...
@@ -77,12 +78,15 @@ class LogfileReopenHandler:
log
.
reopen
()
logger
.
info
(
"Log files reopened successfully"
)
# On Windows, a 'reopen' is useless - the file can not be renamed
# while open, so we perform a trivial 'rotate'.
class
LogfileRotateHandler
:
"""Rotate log files on SIGUSR2. Only called on Windows. This is
registered first, so it should be called after all other SIGUSR2
handlers."""
class
LogfileRotateHandler
(
object
):
"""
Rotate log files on SIGUSR2. Only called on Windows. This is
registered first, so it should be called after all other SIGUSR2
handlers.
"""
def
__init__
(
self
,
loggers
):
self
.
loggers
=
[
log
for
log
in
loggers
if
log
is
not
None
]
...
...
@@ -95,6 +99,7 @@ class LogfileRotateHandler:
handler
.
rotate
()
logger
.
info
(
"Log files rotation complete"
)
def
registerZopeSignals
(
loggers
):
from
signal
import
SIGTERM
,
SIGINT
try
:
...
...
@@ -111,7 +116,7 @@ def registerZopeSignals(loggers):
mod_wsgi
=
True
try
:
from
mod_wsgi
import
version
from
mod_wsgi
import
version
# NOQA
except
ImportError
:
mod_wsgi
=
False
...
...
src/Signals/WinSignalHandler.py
View file @
966f7dfa
...
...
@@ -20,7 +20,7 @@
#
# One event is used per signal, and the event name is based on both the
# Zope process ID and the signal number. For example, assuming a process
# ID of 123, a SIGINT handler would create an event called "Zope-123-2"
# ID of 123, a SIGINT handler would create an event called "Zope-123-2"
# (as signal.SIGINT==2). The logfile reopen handler uses an event named
# "Zope-123-12" (as the logfile handler uses SIGUSR2, which == 12)
...
...
@@ -35,13 +35,14 @@
# NOTE: There is one huge semantic difference between these "signals"
# and signals on Unix. On Windows, the signals are delivered asynchronously
# to a thread inside this module. This thread calls the event handler
# to a thread inside this module. This thread calls the event handler
# directly - there is no magic to switch the call back to the main thread.
# If this is a problem (not currently, but likely later), one option may be
# to add yet another asyncore handler - the thread in this module could
# If this is a problem (not currently, but likely later), one option may be
# to add yet another asyncore handler - the thread in this module could
# then "post" the request to the main thread via this asyncore handler.
import
sys
,
os
import
os
import
sys
import
signal
import
threading
import
asyncore
...
...
@@ -62,7 +63,7 @@ import win32event
import
ntsecuritycon
import
logging
logger
=
logging
.
getLogger
(
"WinSignalHandler"
)
logger
=
logging
.
getLogger
(
"WinSignalHandler"
)
# We simulate signals via win32 named events. This is the event name
# prefix we use - the "signal number" is appended to this name.
...
...
@@ -76,15 +77,16 @@ winver = sys.getwindowsversion()
if
winver
[
0
]
>=
5
and
winver
[
3
]
==
2
:
event_name_prefix
=
"Global
\
\
"
+
event_name_prefix
def
createEventSecurityObject
():
# Create a security object giving World read/write access,
# but only "Owner" modify access.
sa
=
pywintypes
.
SECURITY_ATTRIBUTES
()
sidEveryone
=
pywintypes
.
SID
()
sidEveryone
.
Initialize
(
ntsecuritycon
.
SECURITY_WORLD_SID_AUTHORITY
,
1
)
sidEveryone
.
Initialize
(
ntsecuritycon
.
SECURITY_WORLD_SID_AUTHORITY
,
1
)
sidEveryone
.
SetSubAuthority
(
0
,
ntsecuritycon
.
SECURITY_WORLD_RID
)
sidCreator
=
pywintypes
.
SID
()
sidCreator
.
Initialize
(
ntsecuritycon
.
SECURITY_CREATOR_SID_AUTHORITY
,
1
)
sidCreator
.
Initialize
(
ntsecuritycon
.
SECURITY_CREATOR_SID_AUTHORITY
,
1
)
sidCreator
.
SetSubAuthority
(
0
,
ntsecuritycon
.
SECURITY_CREATOR_OWNER_RID
)
acl
=
pywintypes
.
ACL
()
...
...
@@ -94,9 +96,10 @@ def createEventSecurityObject():
sa
.
SetSecurityDescriptorDacl
(
1
,
acl
,
0
)
return
sa
def
wakeSelect
():
"""Interrupt a sleeping asyncore 'select' call"""
# What is the right thing to do here?
# What is the right thing to do here?
# asyncore.close_all() works, but I fear that would
# prevent the poll based graceful cleanup code from working.
# This seems to work :)
...
...
@@ -104,7 +107,8 @@ def wakeSelect():
if
hasattr
(
obj
,
"pull_trigger"
):
obj
.
pull_trigger
()
class
SignalHandler
:
class
SignalHandler
(
object
):
def
__init__
(
self
):
self
.
registry
=
{}
...
...
@@ -113,7 +117,7 @@ class SignalHandler:
self
.
shutdown_requested
=
False
# Register a "console control handler" for Ctrl+C/Break notification.
SetConsoleCtrlHandler
(
consoleCtrlHandler
)
# Start the thread that is watching for events.
thread
=
threading
.
Thread
(
target
=
self
.
signalCheckerThread
)
# If something goes terribly wrong, don't wait for this thread!
...
...
@@ -126,12 +130,7 @@ class SignalHandler:
logger
.
debug
(
"signal handler shutdown starting."
)
self
.
shutdown_requested
=
1
win32event
.
SetEvent
(
self
.
admin_event_handle
)
# sadly, this can deadlock at shutdown when Ctrl+C is used
# (although not then the event is used to trigger shutdown)
# at least in build 204. Further updates as they come to hand...
# Remove the Windows control handler
#SetConsoleCtrlHandler(consoleCtrlHandler, 0)
self
.
signal_thread
.
join
(
5
)
# should never block for long!
self
.
signal_thread
.
join
(
5
)
# should never block for long!
self
.
registry
=
None
self
.
event_handles
=
None
...
...
@@ -139,7 +138,7 @@ class SignalHandler:
logger
.
debug
(
"signal handler shutdown complete."
)
def
consoleCtrlHandler
(
self
,
ctrlType
):
"""Called by Windows on a new thread whenever a console control
"""Called by Windows on a new thread whenever a console control
event is raised."""
logger
.
debug
(
"Windows control event %d"
%
ctrlType
)
sig
=
None
...
...
@@ -153,13 +152,13 @@ class SignalHandler:
# CTRL_CLOSE_EVENT gives us 5 seconds before displaying
# the "End process" dialog - so treat as 'fast'
sig
=
signal
.
SIGTERM
elif
ctrlType
in
(
win32con
.
CTRL_LOGOFF_EVENT
,
elif
ctrlType
in
(
win32con
.
CTRL_LOGOFF_EVENT
,
win32con
.
CTRL_SHUTDOWN_EVENT
):
# MSDN says:
# "Note that this signal is received only by services.
# Interactive applications are terminated at logoff, so
# "Note that this signal is received only by services.
# Interactive applications are terminated at logoff, so
# they are not present when the system sends this signal."
# We can therefore ignore it (our service framework
# We can therefore ignore it (our service framework
# manages shutdown in this case)
pass
else
:
...
...
@@ -169,9 +168,9 @@ class SignalHandler:
# that we don't wake the select loop until after the shutdown
# flags have been set.
result
=
0
if
sig
is
not
None
and
s
elf
.
registry
.
has_key
(
sig
)
:
if
sig
is
not
None
and
s
ig
in
self
.
registry
:
self
.
signalHandler
(
sig
,
None
)
result
=
1
# don't call other handlers.
result
=
1
# don't call other handlers.
return
result
def
signalCheckerThread
(
self
):
...
...
@@ -210,7 +209,8 @@ class SignalHandler:
# Let the worker thread know there is a new handle.
win32event
.
SetEvent
(
self
.
admin_event_handle
)
signame
=
get_signal_name
(
signum
)
logger
.
debug
(
"Installed sighandler for %s (%s)"
%
(
signame
,
event_name
))
logger
.
debug
(
"Installed sighandler for %s (%s)"
%
(
signame
,
event_name
))
items
.
insert
(
0
,
handler
)
def
getRegisteredSignals
(
self
):
...
...
@@ -226,20 +226,23 @@ class SignalHandler:
for
handler
in
self
.
registry
.
get
(
signum
,
[]):
# Never let a bad handler prevent the standard signal
# handlers from running.
try
:
handler
()
except
SystemExit
,
rc
:
# On Unix, signals are delivered to the main thread, so a
try
:
handler
()
except
SystemExit
as
rc
:
# On Unix, signals are delivered to the main thread, so a
# SystemExit does the right thing. On Windows, we are on
# our own thread, so throwing SystemExit there isn't a great
# idea. Just shutdown the main loop.
logger
.
debug
(
"Trapped SystemExit(%s) - doing Lifetime shutdown"
%
(
rc
,))
logger
.
debug
(
"Trapped SystemExit(%s) - doing Lifetime shutdown"
%
rc
)
Lifetime
.
shutdown
(
rc
)
except
:
logger
.
exception
(
"A handler for %s failed!'"
%
signame
)
wakeSelect
()
# trigger a walk around the Lifetime loop.
wakeSelect
()
# trigger a walk around the Lifetime loop.
_signals
=
None
def
get_signal_name
(
n
):
"""Return the symbolic name for signal n.
...
...
@@ -257,19 +260,20 @@ def get_signal_name(n):
_signals
[
v
]
=
k
# extra ones that aren't (weren't?) in Windows.
for
name
,
val
in
(
"SIGHUP"
,
1
),
(
"SIGUSR1"
,
10
),
(
"SIGUSR2"
,
12
):
if
n
ot
_signals
.
has_key
(
name
)
:
if
n
ame
not
in
_signals
:
_signals
[
val
]
=
name
return
_signals
.
get
(
n
,
'signal %d'
%
n
)
# The win32 ConsoleCtrlHandler
def
consoleCtrlHandler
(
ctrlType
):
# The win32 ConsoleCtrlHandler
return
SignalHandler
.
consoleCtrlHandler
(
ctrlType
)
# The SignalHandler is actually a singleton.
SignalHandler
=
SignalHandler
()
# Need to be careful at shutdown - the 'signal watcher' thread which triggers
# the shutdown may still be running when the main thread terminates and
# Need to be careful at shutdown - the 'signal watcher' thread which triggers
# the shutdown may still be running when the main thread terminates and
# Python starts cleaning up.
atexit
.
register
(
SignalHandler
.
shutdown
)
src/Signals/__init__.py
View file @
966f7dfa
"""
Signals package __init__.py
"""
src/Signals/threads.py
View file @
966f7dfa
...
...
@@ -26,10 +26,10 @@ def dump_threads():
request
=
f
.
f_locals
.
get
(
'request'
)
if
request
is
not
None
:
reqinfo
+=
(
request
.
get
(
'REQUEST_METHOD'
,
''
)
+
' '
+
request
.
get
(
'PATH_INFO'
,
''
))
request
.
get
(
'PATH_INFO'
,
''
))
qs
=
request
.
get
(
'QUERY_STRING'
)
if
qs
:
reqinfo
+=
'?'
+
qs
reqinfo
+=
'?'
+
qs
break
f
=
f
.
f_back
if
reqinfo
:
...
...
@@ -37,8 +37,8 @@ def dump_threads():
output
=
StringIO
()
traceback
.
print_stack
(
frame
,
file
=
output
)
res
.
append
(
"Thread %s%s:
\
n
%s"
%
(
thread_id
,
reqinfo
,
output
.
getvalue
()))
res
.
append
(
"Thread %s%s:
\
n
%s"
%
(
thread_id
,
reqinfo
,
output
.
getvalue
()))
frames
=
None
res
.
append
(
"End of dump"
)
...
...
src/Zope2/Startup/__init__.py
View file @
966f7dfa
...
...
@@ -45,7 +45,7 @@ def get_starter():
return
UnixZopeStarter
()
class
ZopeStarter
:
class
ZopeStarter
(
object
)
:
"""This is a class which starts a Zope server.
Making it a class makes it easier to test.
...
...
@@ -72,7 +72,6 @@ class ZopeStarter:
def
setConfiguration
(
self
,
cfg
):
self
.
cfg
=
cfg
def
sendEvents
(
self
):
notify
(
ProcessStarting
())
...
...
@@ -174,16 +173,14 @@ class ZopeStarter:
'The locale module could not be imported.
\
n
'
'To use localization options, you must ensure
\
n
'
'that the locale module is compiled into your
\
n
'
'Python installation.'
)
'Python installation.'
)
try
:
locale
.
setlocale
(
locale
.
LC_ALL
,
locale_id
)
except
:
raise
ZConfig
.
ConfigurationError
(
'The specified locale "%s" is not supported by your'
'system.
\
n
See your operating system documentation for '
'more
\
n
information on locale support.'
%
locale_id
)
'more
\
n
information on locale support.'
%
locale_id
)
def
setupZServer
(
self
):
# Increase the number of threads
...
...
@@ -197,7 +194,8 @@ class ZopeStarter:
# This one has the delayed listening feature
if
not
server
.
fast_listen
:
server
.
fast_listen
=
True
server
.
listen
(
1024
)
# same value as defined in medusa.http_server.py
# same value as defined in medusa.http_server.py
server
.
listen
(
1024
)
def
setupServers
(
self
):
socket_err
=
(
...
...
@@ -205,17 +203,16 @@ class ZopeStarter:
'This may mean that your user does not have permission to '
'bind to the port which the server is trying to use or the '
'port may already be in use by another application. '
'(%s)'
)
'(%s)'
)
servers
=
[]
for
server
in
self
.
cfg
.
servers
:
# create the server from the server factory
# set up in the config
try
:
servers
.
append
(
server
.
create
())
except
socket
.
error
,
e
:
raise
ZConfig
.
ConfigurationError
(
socket_err
%
(
server
.
servertype
(),
e
[
1
]))
except
socket
.
error
as
e
:
raise
ZConfig
.
ConfigurationError
(
socket_err
%
(
server
.
servertype
(),
e
[
1
]))
self
.
cfg
.
servers
=
servers
def
dropPrivileges
(
self
):
...
...
@@ -372,7 +369,7 @@ def dropPrivileges(cfg):
import
pwd
effective_user
=
cfg
.
effective_user
effective_user
=
cfg
.
effective_user
if
effective_user
is
None
:
msg
=
(
'A user was not specified to setuid to; fix this to '
'start as root (change the effective-user directive '
...
...
@@ -413,15 +410,15 @@ def dropPrivileges(cfg):
os
.
setuid
(
uid
)
logger
.
info
(
'Set effective user to "%s"'
%
effective_user
)
return
1
# for unit testing purposes
return
1
# for unit testing purposes
# DM 2004-11-24: added
def
_name2Ips
(
host
,
isIp_
=
compile
(
r'(\
d+
\.){3}'
).
match
):
'''map a name *host* to the sequence of its ip addresses;
use *host* itself (as sequence) if it already is an ip address.
Thus, if only a specific interface on a host is trusted,
identify it by its ip (and not the host name).
'''
if
isIp_
(
host
):
return
[
host
]
if
isIp_
(
host
):
return
[
host
]
return
gethostbyaddr
(
host
)[
2
]
src/Zope2/Startup/tests/testStarter.py
View file @
966f7dfa
...
...
@@ -34,6 +34,7 @@ from App.config import getConfiguration, setConfiguration
TEMPNAME
=
tempfile
.
mktemp
()
TEMPPRODUCTS
=
os
.
path
.
join
(
TEMPNAME
,
"Products"
)
def
getSchema
():
startup
=
os
.
path
.
dirname
(
Zope2
.
Startup
.
__file__
)
schemafile
=
os
.
path
.
join
(
startup
,
'zopeschema.xml'
)
...
...
@@ -45,10 +46,11 @@ def getSchema():
logger_states
=
{}
for
name
in
(
None
,
'trace'
,
'access'
):
logger
=
logging
.
getLogger
(
name
)
logger_states
[
name
]
=
{
'level'
:
logger
.
level
,
'propagate'
:
logger
.
propagate
,
'handlers'
:
logger
.
handlers
,
'filters'
:
logger
.
filters
}
logger_states
[
name
]
=
{
'level'
:
logger
.
level
,
'propagate'
:
logger
.
propagate
,
'handlers'
:
logger
.
handlers
,
'filters'
:
logger
.
filters
}
class
ZopeStarterTestCase
(
LoggingTestHelper
,
unittest
.
TestCase
):
...
...
@@ -94,7 +96,7 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
try
:
os
.
mkdir
(
TEMPNAME
)
os
.
mkdir
(
TEMPPRODUCTS
)
except
OSError
,
why
:
except
OSError
as
why
:
if
why
==
17
:
# already exists
pass
...
...
@@ -110,10 +112,10 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
conf
=
self
.
load_config_text
(
"""
instancehome <<INSTANCE_HOME>>
locale en_GB"""
)
except
ZConfig
.
DataConversionError
,
e
:
except
ZConfig
.
DataConversionError
as
e
:
# Skip this test if we don't have support.
if
e
.
message
.
startswith
(
'The specified locale "en_GB" is not supported'
):
'The specified locale "en_GB" is not supported'
):
return
raise
starter
=
self
.
get_starter
(
conf
)
...
...
@@ -146,16 +148,12 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
# startup handler should take on the level of the event log handler
# with the lowest level
logger
=
starter
.
event_logger
self
.
assertEqual
(
starter
.
startup_handler
.
level
,
15
)
# 15 is BLATHER
self
.
assertEqual
(
starter
.
startup_handler
.
level
,
15
)
# 15 is BLATHER
self
.
assert_
(
starter
.
startup_handler
in
logger
.
handlers
)
self
.
assertEqual
(
logger
.
level
,
15
)
# We expect a debug handler and the startup handler:
self
.
assertEqual
(
len
(
logger
.
handlers
),
2
)
# XXX need to check that log messages get written to
# sys.stderr, not that the stream identity for the startup
# handler matches
#self.assertEqual(starter.startup_handler.stream, sys.stderr)
conf
=
self
.
load_config_text
(
"""
instancehome <<INSTANCE_HOME>>
debug-mode off
...
...
@@ -168,10 +166,6 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
</eventlog>"""
)
starter
=
self
.
get_starter
(
conf
)
starter
.
setupInitialLogging
()
# XXX need to check that log messages get written to
# sys.stderr, not that the stream identity for the startup
# handler matches
#self.assertNotEqual(starter.startup_handler.stream, sys.stderr)
def
testSetupZServerThreads
(
self
):
conf
=
self
.
load_config_text
(
"""
...
...
@@ -193,7 +187,7 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
</http-server>
<ftp-server>
address %(ftp)s
</ftp-server>"""
%
dict
(
http
=
port
,
ftp
=
port
+
1
)
</ftp-server>"""
%
dict
(
http
=
port
,
ftp
=
port
+
1
)
)
starter
=
self
.
get_starter
(
conf
)
# do the job the 'handler' would have done (call prepare)
...
...
@@ -207,7 +201,7 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
self
.
assertEqual
(
conf
.
servers
[
1
].
__class__
,
ZServer
.
FTPServer
)
finally
:
del
conf
.
servers
# should release servers
del
conf
.
servers
# should release servers
pass
def
testDropPrivileges
(
self
):
...
...
@@ -216,8 +210,10 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
if
os
.
name
!=
'posix'
:
return
_old_getuid
=
os
.
getuid
def
_return0
():
return
0
def
make_starter
(
conf
):
# remove the debug handler, since we don't want junk on
# stderr for the tests
...
...
@@ -292,8 +288,10 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
self
.
assertEqual
(
logger
.
level
,
logging
.
INFO
)
l
=
open
(
os
.
path
.
join
(
TEMPNAME
,
'event.log'
)).
read
()
self
.
assertTrue
(
l
.
find
(
'hello'
)
>
-
1
)
self
.
assertTrue
(
os
.
path
.
exists
(
os
.
path
.
join
(
TEMPNAME
,
'Z2.log'
)))
self
.
assertTrue
(
os
.
path
.
exists
(
os
.
path
.
join
(
TEMPNAME
,
'trace.log'
)))
self
.
assertTrue
(
os
.
path
.
exists
(
os
.
path
.
join
(
TEMPNAME
,
'Z2.log'
)))
self
.
assertTrue
(
os
.
path
.
exists
(
os
.
path
.
join
(
TEMPNAME
,
'trace.log'
)))
finally
:
for
name
in
(
'event.log'
,
'Z2.log'
,
'trace.log'
):
try
:
...
...
@@ -355,12 +353,11 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
conf
=
self
.
load_config_text
(
"""
instancehome <<INSTANCE_HOME>>
python-check-interval %d
"""
%
newcheckinterval
)
"""
%
newcheckinterval
)
try
:
starter
=
self
.
get_starter
(
conf
)
starter
.
setupInterpreter
()
self
.
assertEqual
(
sys
.
getcheckinterval
()
,
newcheckinterval
)
self
.
assertEqual
(
sys
.
getcheckinterval
(),
newcheckinterval
)
finally
:
sys
.
setcheckinterval
(
oldcheckinterval
)
...
...
@@ -369,7 +366,7 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
try
:
os
.
mkdir
(
TEMPNAME
)
os
.
mkdir
(
TEMPPRODUCTS
)
except
OSError
,
why
:
except
OSError
as
why
:
if
why
==
errno
.
EEXIST
:
# already exists
pass
...
...
@@ -392,7 +389,3 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
except
:
pass
setConfiguration
(
old_config
)
def
test_suite
():
return
unittest
.
makeSuite
(
ZopeStarterTestCase
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment