/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4988.10.3 by John Arbash Meinel
Merge bzr.dev 5007, resolve conflict, update NEWS
1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
16
7344.2.1 by Martin
Relocate the bzr log file out of $HOME
17
"""Transport decorator that logs transport operations to brz.log."""
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
18
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
19
# see also the transportstats plugin, which gives you some summary information
20
# in a machine-readable dump
21
22
import time
23
import types
24
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
25
from ..trace import mutter
26
from ..transport import decorator
5017.3.11 by Vincent Ladeuil
Move LogDecoratorServer to bzrlib.tests.test_server
27
28
29
class TransportLogDecorator(decorator.TransportDecorator):
7344.2.1 by Martin
Relocate the bzr log file out of $HOME
30
    """Decorator for Transports that logs interesting operations to brz.log.
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
31
32
    In general we want to log things that usually take a network round trip
33
    and may be slow.
34
35
    Not all operations are logged yet.
4491.2.2 by Martin Pool
TransportLogDecorator.readv must return a generator
36
7195.5.1 by Martin
Fix remaining whitespace lint in codebase
37
    See also TransportTraceDecorator, that records a machine-readable log in
4491.2.2 by Martin Pool
TransportLogDecorator.readv must return a generator
38
    memory for eg testing.
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
39
    """
40
41
    def __init__(self, *args, **kw):
42
        super(TransportLogDecorator, self).__init__(*args, **kw)
7143.15.2 by Jelmer Vernooij
Run autopep8.
43
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
44
        def _make_hook(hookname):
45
            def _hook(relpath, *args, **kw):
3675.1.2 by Martin Pool
log+ decorator needs special handling for iter_files_recursive, which does not take a path
46
                return self._log_and_call(hookname, relpath, *args, **kw)
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
47
            return _hook
6621.2.27 by Martin
Fix failure in per_transport tests from treating list as a path
48
        # GZ 2017-05-21: Not all methods take relpath as first argument, for
49
        # instance copy_to takes list of relpaths. Also, unclear on url vs
50
        # filesystem path split. Needs tidying up.
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
51
        for methodname in (
7143.15.2 by Jelmer Vernooij
Run autopep8.
52
                'append_bytes',
53
                'append_file',
54
                'copy_to',
55
                'delete',
56
                'get',
57
                'has',
58
                'open_write_stream',
59
                'mkdir',
60
                'move',
61
                'put_bytes', 'put_bytes_non_atomic', 'put_file put_file_non_atomic',
62
                'list_dir', 'lock_read', 'lock_write',
63
                'readv', 'rename', 'rmdir',
64
                'stat',
65
                'ulock',
66
                ):
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
67
            setattr(self, methodname, _make_hook(methodname))
68
69
    @classmethod
70
    def _get_url_prefix(self):
71
        return 'log+'
72
3675.1.2 by Martin Pool
log+ decorator needs special handling for iter_files_recursive, which does not take a path
73
    def iter_files_recursive(self):
74
        # needs special handling because it does not have a relpath parameter
75
        mutter("%s %s"
7143.15.2 by Jelmer Vernooij
Run autopep8.
76
               % ('iter_files_recursive', self._decorated.base))
3675.1.2 by Martin Pool
log+ decorator needs special handling for iter_files_recursive, which does not take a path
77
        return self._call_and_log_result('iter_files_recursive', (), {})
78
79
    def _log_and_call(self, methodname, relpath, *args, **kwargs):
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
80
        if kwargs:
81
            kwargs_str = dict(kwargs)
82
        else:
83
            kwargs_str = ''
84
        mutter("%s %s %s %s"
6621.2.27 by Martin
Fix failure in per_transport tests from treating list as a path
85
               % (methodname, relpath,
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
86
                  self._shorten(self._strip_tuple_parens(args)),
87
                  kwargs_str))
3675.1.2 by Martin Pool
log+ decorator needs special handling for iter_files_recursive, which does not take a path
88
        return self._call_and_log_result(methodname, (relpath,) + args, kwargs)
89
90
    def _call_and_log_result(self, methodname, args, kwargs):
91
        before = time.time()
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
92
        try:
3675.1.2 by Martin Pool
log+ decorator needs special handling for iter_files_recursive, which does not take a path
93
            result = getattr(self._decorated, methodname)(*args, **kwargs)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
94
        except Exception as e:
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
95
            mutter("  --> %s" % e)
96
            mutter("      %.03fs" % (time.time() - before))
97
            raise
98
        return self._show_result(before, methodname, result)
99
100
    def _show_result(self, before, methodname, result):
101
        result_len = None
102
        if isinstance(result, types.GeneratorType):
4491.2.2 by Martin Pool
TransportLogDecorator.readv must return a generator
103
            # We now consume everything from the generator so that we can show
104
            # the results and the time it took to get them.  However, to keep
105
            # compatibility with callers that may specifically expect a result
106
            # (see <https://launchpad.net/bugs/340347>) we also return a new
107
            # generator, reset to the starting position.
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
108
            result = list(result)
4491.2.2 by Martin Pool
TransportLogDecorator.readv must return a generator
109
            return_result = iter(result)
110
        else:
111
            return_result = result
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
112
        # Is this an io object with a getvalue() method?
113
        getvalue = getattr(result, 'getvalue', None)
114
        if getvalue is not None:
115
            val = repr(getvalue())
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
116
            result_len = len(val)
117
            shown_result = "%s(%s) (%d bytes)" % (result.__class__.__name__,
7143.15.2 by Jelmer Vernooij
Run autopep8.
118
                                                  self._shorten(val), result_len)
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
119
        elif methodname == 'readv':
120
            num_hunks = len(result)
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
121
            total_bytes = sum((len(d) for o, d in result))
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
122
            shown_result = "readv response, %d hunks, %d total bytes" % (
123
                num_hunks, total_bytes)
124
            result_len = total_bytes
125
        else:
126
            shown_result = self._shorten(self._strip_tuple_parens(result))
127
        mutter("  --> %s" % shown_result)
4491.2.7 by Martin Pool
Suppress now-redundant rate and time display in log+ output
128
        # The log decorator no longer shows the elapsed time or transfer rate
129
        # because they're available in the log prefixes and the transport
130
        # activity display respectively.
131
        if False:
132
            elapsed = time.time() - before
133
            if result_len and elapsed > 0:
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
134
                # this is the rate of higher-level data, not the raw network
135
                # speed using base-10 units (see HACKING.txt).
136
                mutter("      %9.03fs %8dkB/s"
7143.15.2 by Jelmer Vernooij
Run autopep8.
137
                       % (elapsed, result_len / elapsed / 1000))
4491.2.7 by Martin Pool
Suppress now-redundant rate and time display in log+ output
138
            else:
139
                mutter("      %9.03fs" % (elapsed))
4491.2.2 by Martin Pool
TransportLogDecorator.readv must return a generator
140
        return return_result
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
141
142
    def _shorten(self, x):
143
        if len(x) > 70:
144
            x = x[:67] + '...'
145
        return x
146
147
    def _strip_tuple_parens(self, t):
148
        t = repr(t)
149
        if t[0] == '(' and t[-1] == ')':
150
            t = t[1:-1]
151
        return t
152
153
154
def get_test_permutations():
155
    """Return the permutations to be used in testing."""
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
156
    from ..tests import test_server
5017.3.11 by Vincent Ladeuil
Move LogDecoratorServer to bzrlib.tests.test_server
157
    return [(TransportLogDecorator, test_server.LogDecoratorServer)]