[Checkins] SVN: zc.zservertracelog/trunk/ merged in changes from alex-tests branch (r90470-90718).
Alex Smith
asmith at zope.com
Tue Sep 2 14:36:28 EDT 2008
Log message for revision 90722:
merged in changes from alex-tests branch (r90470-90718).
Changed:
_U zc.zservertracelog/trunk/
A zc.zservertracelog/trunk/CHANGES.txt
U zc.zservertracelog/trunk/buildout.cfg
U zc.zservertracelog/trunk/setup.py
A zc.zservertracelog/trunk/src/zc/zservertracelog/README.txt
U zc.zservertracelog/trunk/src/zc/zservertracelog/configure.zcml
A zc.zservertracelog/trunk/src/zc/zservertracelog/tests.py
U zc.zservertracelog/trunk/src/zc/zservertracelog/tracelog.py
-=-
Property changes on: zc.zservertracelog/trunk
___________________________________________________________________
Name: svn:ignore
- develop-eggs
parts
dist
bin
trace.log
+ develop-eggs
parts
dist
bin
eggs
.installed.cfg
trace.log
Copied: zc.zservertracelog/trunk/CHANGES.txt (from rev 90721, zc.zservertracelog/branches/alex-tests/CHANGES.txt)
===================================================================
--- zc.zservertracelog/trunk/CHANGES.txt (rev 0)
+++ zc.zservertracelog/trunk/CHANGES.txt 2008-09-02 18:36:28 UTC (rev 90722)
@@ -0,0 +1,11 @@
+
+=========
+ Changes
+=========
+
+
+0.4 (unreleased)
+================
+
+* added automated tests.
+
Modified: zc.zservertracelog/trunk/buildout.cfg
===================================================================
--- zc.zservertracelog/trunk/buildout.cfg 2008-09-02 18:22:17 UTC (rev 90721)
+++ zc.zservertracelog/trunk/buildout.cfg 2008-09-02 18:36:28 UTC (rev 90722)
@@ -1,7 +1,28 @@
[buildout]
develop = .
-parts = instance tracereport
+parts =
+ instance
+ interpreter
+ tags
+ test
+ tracereport
+[interpreter]
+recipe = zc.recipe.egg
+interpreter = py
+eggs =
+ zc.zservertracelog
+
+[tags]
+recipe = z3c.recipe.tag:tags
+eggs =
+ zc.zservertracelog
+
+[test]
+recipe = zc.recipe.testrunner
+eggs =
+ zc.zservertracelog [test]
+
[zope3]
location =
Modified: zc.zservertracelog/trunk/setup.py
===================================================================
--- zc.zservertracelog/trunk/setup.py 2008-09-02 18:22:17 UTC (rev 90721)
+++ zc.zservertracelog/trunk/setup.py 2008-09-02 18:36:28 UTC (rev 90722)
@@ -27,11 +27,20 @@
description = 'Zope 3 tracelog implementation for zserver',
license = 'ZPL 2.1',
keywords = 'zope3',
-
packages = find_packages('src'),
namespace_packages = ['zc'],
package_dir = {'': 'src'},
- install_requires = 'setuptools',
+ install_requires = [
+ 'setuptools',
+ 'zope.app.appsetup',
+ 'zope.app.server',
+ 'zope.app.wsgi',
+ 'zope.server',
+ ],
+ extras_require = dict(
+ test = [
+ 'zope.testing',
+ ]),
include_package_data = True,
zip_safe = False,
entry_points=entry_points,
Copied: zc.zservertracelog/trunk/src/zc/zservertracelog/README.txt (from rev 90721, zc.zservertracelog/branches/alex-tests/src/zc/zservertracelog/README.txt)
===================================================================
--- zc.zservertracelog/trunk/src/zc/zservertracelog/README.txt (rev 0)
+++ zc.zservertracelog/trunk/src/zc/zservertracelog/README.txt 2008-09-02 18:36:28 UTC (rev 90722)
@@ -0,0 +1,116 @@
+==================
+ ZServer TraceLog
+==================
+
+A tracelog is a kind of access log that records several low-level events for
+each request. Each log entry starts with a record type, a request identifier
+and the time. Some log records have additional data.
+
+ >>> import zc.zservertracelog.tracelog
+ >>> import zope.app.appsetup.interfaces
+
+For these examples, we'll add a log handler that outputs to standard out.
+
+ >>> import logging
+ >>> import sys
+ >>> stdout_handler = logging.StreamHandler(sys.stdout)
+
+ >>> logger = logging.getLogger('zc.tracelog')
+ >>> logger.setLevel(logging.INFO)
+ >>> logger.addHandler(stdout_handler)
+
+
+Server Startup
+==============
+
+There is an event handler to log when the Z server starts.
+
+ >>> zc.zservertracelog.tracelog.started(
+ ... zope.app.appsetup.interfaces.ProcessStarting())
+ S 0 2008-08-26T11:55:00
+
+
+Tracing Applications
+====================
+
+The tracelog machinery is implemented as a WSGI layer, so we'll pass a fake
+WSGI application to tracelog for these examples.
+
+ >>> faux_app = FauxApplication()
+
+Now, let's create an instance of the tracelog server.
+
+ >>> addr, port = '127.0.0.1', 12345
+
+ >>> trace_server = zc.zservertracelog.tracelog.Server(
+ ... faux_app, None, addr, port)
+
+Let's also define a convenience function for processing requests.
+
+ >>> def invokeRequest(req):
+ ... channel = trace_server.channel_class(trace_server, None, addr)
+ ... channel.received(req)
+
+Process a simple request.
+
+ >>> req1 = """\
+ ... GET /test-req1 HTTP/1.1
+ ... Host: www.example.com
+ ...
+ ... """
+
+ >>> invokeRequest(req1)
+ B 23423600 2008-08-27T10:54:08 GET /test-req1
+ I 23423600 2008-08-27T10:54:08 0
+ C 23423600 2008-08-27T10:54:08
+ A 23423600 2008-08-27T10:54:08 200 ?
+ E 23423600 2008-08-27T10:54:08
+
+
+Application Errors
+==================
+
+The tracelog will also log application errors. To show this, we'll set up
+our test application to raise an error when called.
+
+ >>> def app_failure(*args, **kwargs):
+ ... raise Exception('oh noes!')
+ >>> faux_app.app_hook = app_failure
+
+Invoking the request produces log entries for every trace point, and the
+application error is written to the *Application End (A)* trace entry.
+
+ >>> try:
+ ... invokeRequest(req1)
+ ... except:
+ ... pass
+ B 21663984 2008-09-02T11:19:26 GET /test-req1
+ I 21663984 2008-09-02T11:19:26 0
+ C 21663984 2008-09-02T11:19:26
+ A 21663984 2008-09-02T11:19:26 Error: oh noes!
+ E 21663984 2008-09-02T11:19:26
+
+
+Response Errors
+===============
+
+The tracelog also handles errors that can be generated when writing to the
+response. To show this, we'll set up our test application to return a
+response that produces an error when written to.
+
+ >>> def response_of_wrong_type(*args, **kwargs):
+ ... return object()
+ >>> faux_app.app_hook = response_of_wrong_type
+
+Invoking the request produces log entries for every trace point, and the
+error is written to the *Request End (E)* trace entry.
+
+ >>> try:
+ ... invokeRequest(req1)
+ ... except:
+ ... pass
+ B 21651664 2008-09-02T13:59:02 GET /test-req1
+ I 21651664 2008-09-02T13:59:02 0
+ C 21651664 2008-09-02T13:59:02
+ A 21651664 2008-09-02T13:59:02 200 ?
+ E 21651664 2008-09-02T13:59:02 Error: iteration over non-sequence
Modified: zc.zservertracelog/trunk/src/zc/zservertracelog/configure.zcml
===================================================================
--- zc.zservertracelog/trunk/src/zc/zservertracelog/configure.zcml 2008-09-02 18:22:17 UTC (rev 90721)
+++ zc.zservertracelog/trunk/src/zc/zservertracelog/configure.zcml 2008-09-02 18:36:28 UTC (rev 90722)
@@ -13,4 +13,5 @@
/>
<subscriber handler=".tracelog.started" />
+
</configure>
Copied: zc.zservertracelog/trunk/src/zc/zservertracelog/tests.py (from rev 90721, zc.zservertracelog/branches/alex-tests/src/zc/zservertracelog/tests.py)
===================================================================
--- zc.zservertracelog/trunk/src/zc/zservertracelog/tests.py (rev 0)
+++ zc.zservertracelog/trunk/src/zc/zservertracelog/tests.py 2008-09-02 18:36:28 UTC (rev 90722)
@@ -0,0 +1,60 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Visible Source
+# License, Version 1.0 (ZVSL). A copy of the ZVSL 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.
+#
+##############################################################################
+"""tracelog tests
+"""
+__docformat__ = "reStructuredText"
+
+from zope.testing import doctest
+import re
+import unittest
+import zope.testing.renormalizing
+
+
+checker = zope.testing.renormalizing.RENormalizing([
+ # normalize the channel id and iso8601 timestamp
+ (re.compile(r'-?\d+ \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}'),
+ '23418928 2008-08-26T10:55:00'),
+ ])
+
+
+_null_app = lambda environ, start_response: None
+
+
+class FauxApplication(object):
+ """Fake WSGI application. Doesn't need to do much!"""
+
+ app_hook = None
+
+ def __call__(self, environ, start_response):
+ app = self.app_hook or _null_app
+ return app(environ, start_response)
+
+
+def setUp(test):
+ test.globs['FauxApplication'] = FauxApplication
+
+
+def test_suite():
+ return unittest.TestSuite([
+ doctest.DocFileTest(
+ 'README.txt',
+ optionflags=(
+ doctest.NORMALIZE_WHITESPACE
+ | doctest.ELLIPSIS
+ | doctest.INTERPRET_FOOTNOTES),
+ checker=checker,
+ setUp=setUp,
+ ),
+ ])
Modified: zc.zservertracelog/trunk/src/zc/zservertracelog/tracelog.py
===================================================================
--- zc.zservertracelog/trunk/src/zc/zservertracelog/tracelog.py 2008-09-02 18:22:17 UTC (rev 90721)
+++ zc.zservertracelog/trunk/src/zc/zservertracelog/tracelog.py 2008-09-02 18:36:28 UTC (rev 90722)
@@ -13,21 +13,19 @@
##############################################################################
"""Crude Tracelog Hack for ZServer
"""
-import datetime, re, logging
-
-import zope.component
-
-from zope.server.http.commonaccesslogger import CommonAccessLogger
+from zope.app.server import servertype
+from zope.app.wsgi import WSGIPublisherApplication
from zope.server.http import wsgihttpserver
+from zope.server.http.commonaccesslogger import CommonAccessLogger
+import datetime
+import logging
+import re
+import zope.app.appsetup.interfaces
+import zope.component
import zope.server.http.httprequestparser
-
import zope.server.http.httpserverchannel
-from zope.app.server import servertype
-from zope.app.wsgi import WSGIPublisherApplication
-import zope.app.appsetup.interfaces
-
logger = logging.getLogger('zc.tracelog')
def now():
@@ -79,8 +77,9 @@
logger.info("E %s %s", id(task.channel), now())
raise
else:
+ accumulated_headers = getattr(task, 'accumulated_headers') or ()
length = [h.split(': ')[1].strip()
- for h in getattr(task, 'accumulated_headers', ())
+ for h in accumulated_headers
if h.lower().startswith('content-length: ')]
if length:
length = length[0]
More information about the Checkins
mailing list