/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
543.2.1 by Jelmer Vernooij
Sort Python import definitions with isort
37
437 by John Arbash Meinel
Import sys at the start of loggerhead/__init__.py we use it as part of startup.
38
import sys
39
527.1.2 by Colin Watson
Modernize packaging.
40
from packaging.version import Version
41
42
try:
43
    version_info = Version(importlib_metadata.version("loggerhead")).release
44
except importlib_metadata.PackageNotFoundError:
45
    # Support running tests from the build tree without installation.
46
    version_info = None
262.2.2 by Martin Pool
Merge in 'serve --http' based on code from mwh
47
491.2.28 by Jelmer Vernooij
Remove python path hackery.
48
import breezy
49
from breezy import commands
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
543.1.1 by Jelmer Vernooij
Add support for 'python -m loggerhead'
70
        from .loggerhead.__main__ import setup_logging
491.2.54 by Jelmer Vernooij
Try local loggerhead first, then fall back to system one.
71
    except ImportError:
72
        from loggerhead.apps.http_head import HeadMiddleware
73
        from loggerhead.apps.transport import BranchesFromTransportRoot
74
        from loggerhead.config import LoggerheadConfig
543.1.1 by Jelmer Vernooij
Add support for 'python -m loggerhead'
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:
539.2.1 by Jelmer Vernooij
When tests are not installed, don't register them.
124
        from breezy.trace import mutter
125
        mutter(
126
            'loggerhead tests not installed, not registering tests')
127
    else:
128
        basic_tests.addTest(test_suite())
491.2.28 by Jelmer Vernooij
Remove python path hackery.
129
    return basic_tests