/loggerhead/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/loggerhead/trunk
423.2.1 by John Arbash Meinel
Start working on some code to do load testing of loggerhead.
1
# Copyright 2009, 2010, 2011 Canonical Ltd
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
467.2.1 by Toshio Kuratomi
Change to the FSF address in license headers
15
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335  USA
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
16
262.2.1 by Martin Pool
Stub code to allow loggerhead to load as a plugin
17
18
# This file allows loggerhead to be treated as a plugin for bzr.
19
#
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
20
# XXX: Because loggerhead already contains a loggerhead directory, much of the
491.2.1 by Jelmer Vernooij
s/bzrlib/breezy/
21
# code is going to appear loaded at breezy.plugins.loggerhead.loggerhead.
22
# This seems like the easiest thing, because breezy wants the top-level plugin
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
23
# directory to be the module, but when it's used as a library people expect
24
# the source directory to contain a directory called loggerhead.  -- mbp
25
# 20090123
26
27
"""Loggerhead web viewer for Bazaar branches.
28
329.2.1 by Matt Nordhoff
Strip trailing whitespace
29
This provides a new option "--http" to the "bzr serve" command, that
262.2.4 by Martin Pool
Act as a plugin only when loaded by bzr; update docs
30
starts a web server to browse the contents of a branch.
31
"""
262.2.1 by Martin Pool
Stub code to allow loggerhead to load as a plugin
32
527.1.2 by Colin Watson
Modernize packaging.
33
try:
34
    import importlib.metadata as importlib_metadata
35
except ImportError:
36
    import importlib_metadata
437 by John Arbash Meinel
Import sys at the start of loggerhead/__init__.py we use it as part of startup.
37
import sys
38
527.1.2 by Colin Watson
Modernize packaging.
39
from packaging.version import Version
40
41
try:
42
    version_info = Version(importlib_metadata.version("loggerhead")).release
43
except importlib_metadata.PackageNotFoundError:
44
    # Support running tests from the build tree without installation.
45
    version_info = None
262.2.2 by Martin Pool
Merge in 'serve --http' based on code from mwh
46
491.2.28 by Jelmer Vernooij
Remove python path hackery.
47
import breezy
48
from breezy import commands
49
50
from breezy.transport import transport_server_registry
51
52
DEFAULT_HOST = '0.0.0.0'
53
DEFAULT_PORT = 8080
54
HELP = ('Loggerhead, a web-based code viewer and server. (default port: %d)' %
55
        (DEFAULT_PORT,))
56
57
58
def serve_http(transport, host=None, port=None, inet=None, client_timeout=None):
59
    # TODO: if we supported inet to pass requests in and respond to them,
60
    #       then it would be easier to test the full stack, but it probably
61
    #       means routing around paste.httpserver.serve which probably
62
    #       isn't testing the full stack
63
    from paste.httpexceptions import HTTPExceptionHandler
64
    from paste.httpserver import serve
65
491.2.54 by Jelmer Vernooij
Try local loggerhead first, then fall back to system one.
66
    try:
67
        from .loggerhead.apps.http_head import HeadMiddleware
68
        from .loggerhead.apps.transport import BranchesFromTransportRoot
69
        from .loggerhead.config import LoggerheadConfig
70
        from .loggerhead.main import setup_logging
71
    except ImportError:
72
        from loggerhead.apps.http_head import HeadMiddleware
73
        from loggerhead.apps.transport import BranchesFromTransportRoot
74
        from loggerhead.config import LoggerheadConfig
75
        from loggerhead.main import setup_logging
491.2.28 by Jelmer Vernooij
Remove python path hackery.
76
77
    if host is None:
78
        host = DEFAULT_HOST
79
    if port is None:
80
        port = DEFAULT_PORT
81
    argv = ['--host', host, '--port', str(port), '--', transport.base]
82
    if not transport.is_readonly():
83
        argv.insert(0, '--allow-writes')
84
    config = LoggerheadConfig(argv)
85
    setup_logging(config, init_logging=False, log_file=sys.stderr)
86
    app = BranchesFromTransportRoot(transport.base, config)
87
    # Bug #758618, HeadMiddleware seems to break HTTPExceptionHandler from
88
    # actually sending appropriate return codes to the client. Since nobody
89
    # desperately needs HeadMiddleware right now, just ignoring it.
90
    # app = HeadMiddleware(app)
91
    app = HTTPExceptionHandler(app)
92
    serve(app, host=host, port=port)
93
94
transport_server_registry.register('http', serve_http, help=HELP)
95
96
class cmd_load_test_loggerhead(commands.Command):
97
    """Run a load test against a live loggerhead instance.
98
99
    Pass in the name of a script file to run. See loggerhead/load_test.py
100
    for a description of the file format.
101
    """
102
103
    hidden = True
104
    takes_args = ["filename"]
105
106
    def run(self, filename):
491.2.54 by Jelmer Vernooij
Try local loggerhead first, then fall back to system one.
107
        try:
108
            from .loggerhead.loggerhead import load_test
109
        except ImportError:
110
            from loggerhead.loggerhead import load_test
491.2.28 by Jelmer Vernooij
Remove python path hackery.
111
        script = load_test.run_script(filename)
112
        for thread_id in sorted(script._threads):
113
            worker = script._threads[thread_id][0]
114
            for url, success, time in worker.stats:
115
                self.outf.write(' %5.3fs %s %s\n'
116
                                % (time, str(success)[0], url))
117
118
commands.register_command(cmd_load_test_loggerhead)
119
120
def load_tests(loader, basic_tests, pattern):
491.2.54 by Jelmer Vernooij
Try local loggerhead first, then fall back to system one.
121
    try:
122
        from .loggerhead.tests import test_suite
123
    except ImportError:
124
        from loggerhead.tests import test_suite
491.2.40 by Jelmer Vernooij
Fix some more tests on Python 3.
125
    basic_tests.addTest(test_suite())
491.2.28 by Jelmer Vernooij
Remove python path hackery.
126
    return basic_tests