bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
1  | 
# Copyright (C) 2007 Canonical Ltd
 | 
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
 | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
16  | 
|
17  | 
"""Implementation of Transport that traces transport operations.
 | 
|
18  | 
||
| 
2745.5.4
by Robert Collins
 Review feedback.  | 
19  | 
This does not change the transport behaviour at all, merely records every call
 | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
20  | 
and then delegates it.
 | 
21  | 
"""
 | 
|
22  | 
||
23  | 
from bzrlib.transport.decorator import TransportDecorator, DecoratorServer  | 
|
24  | 
||
25  | 
||
26  | 
class TransportTraceDecorator(TransportDecorator):  | 
|
27  | 
"""A tracing decorator for Transports.  | 
|
28  | 
||
29  | 
    Calls that potentially perform IO are logged to self._activity. The
 | 
|
30  | 
    _activity attribute is shared as the transport is cloned, but not if a new
 | 
|
31  | 
    transport is created without cloning.
 | 
|
| 
2745.5.4
by Robert Collins
 Review feedback.  | 
32  | 
|
33  | 
    Not all operations are logged at this point, if you need an unlogged
 | 
|
34  | 
    operation please add a test to the tests of this transport, for the logging
 | 
|
35  | 
    of the operation you want logged.
 | 
|
| 
4491.2.2
by Martin Pool
 TransportLogDecorator.readv must return a generator  | 
36  | 
|
37  | 
    See also TransportLogDecorator, that records a machine-readable log in 
 | 
|
38  | 
    memory for eg testing.
 | 
|
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
39  | 
    """
 | 
40  | 
||
41  | 
def __init__(self, url, _decorated=None, _from_transport=None):  | 
|
42  | 
"""Set the 'base' path where files will be stored.  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
43  | 
|
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
44  | 
        _decorated is a private parameter for cloning.
 | 
45  | 
        """
 | 
|
46  | 
TransportDecorator.__init__(self, url, _decorated)  | 
|
47  | 
if _from_transport is None:  | 
|
48  | 
            # newly created
 | 
|
49  | 
self._activity = []  | 
|
50  | 
else:  | 
|
51  | 
            # cloned
 | 
|
52  | 
self._activity = _from_transport._activity  | 
|
53  | 
||
54  | 
def append_file(self, relpath, f, mode=None):  | 
|
55  | 
"""See Transport.append_file()."""  | 
|
56  | 
return self._decorated.append_file(relpath, f, mode=mode)  | 
|
57  | 
||
58  | 
def append_bytes(self, relpath, bytes, mode=None):  | 
|
59  | 
"""See Transport.append_bytes()."""  | 
|
60  | 
return self._decorated.append_bytes(relpath, bytes, mode=mode)  | 
|
61  | 
||
62  | 
def delete(self, relpath):  | 
|
63  | 
"""See Transport.delete()."""  | 
|
| 
3515.3.1
by Robert Collins
 (robertc) More tracing for trace+ transport. (Robert Collins)  | 
64  | 
self._activity.append(('delete', relpath))  | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
65  | 
return self._decorated.delete(relpath)  | 
66  | 
||
67  | 
def delete_tree(self, relpath):  | 
|
68  | 
"""See Transport.delete_tree()."""  | 
|
69  | 
return self._decorated.delete_tree(relpath)  | 
|
70  | 
||
71  | 
    @classmethod
 | 
|
72  | 
def _get_url_prefix(self):  | 
|
73  | 
"""Tracing transports are identified by 'trace+'"""  | 
|
74  | 
return 'trace+'  | 
|
75  | 
||
76  | 
def get(self, relpath):  | 
|
77  | 
"""See Transport.get()."""  | 
|
| 
3675.1.1
by Martin Pool
 Merge and update log+ transport decorator  | 
78  | 
self._trace(('get', relpath))  | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
79  | 
return self._decorated.get(relpath)  | 
80  | 
||
81  | 
def get_smart_client(self):  | 
|
82  | 
return self._decorated.get_smart_client()  | 
|
83  | 
||
84  | 
def has(self, relpath):  | 
|
85  | 
"""See Transport.has()."""  | 
|
86  | 
return self._decorated.has(relpath)  | 
|
87  | 
||
88  | 
def is_readonly(self):  | 
|
89  | 
"""See Transport.is_readonly."""  | 
|
90  | 
return self._decorated.is_readonly()  | 
|
91  | 
||
92  | 
def mkdir(self, relpath, mode=None):  | 
|
93  | 
"""See Transport.mkdir()."""  | 
|
| 
3675.1.1
by Martin Pool
 Merge and update log+ transport decorator  | 
94  | 
self._trace(('mkdir', relpath, mode))  | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
95  | 
return self._decorated.mkdir(relpath, mode)  | 
96  | 
||
97  | 
def open_write_stream(self, relpath, mode=None):  | 
|
98  | 
"""See Transport.open_write_stream."""  | 
|
99  | 
return self._decorated.open_write_stream(relpath, mode=mode)  | 
|
100  | 
||
101  | 
def put_file(self, relpath, f, mode=None):  | 
|
102  | 
"""See Transport.put_file()."""  | 
|
103  | 
return self._decorated.put_file(relpath, f, mode)  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
104  | 
|
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
105  | 
def put_bytes(self, relpath, bytes, mode=None):  | 
106  | 
"""See Transport.put_bytes()."""  | 
|
| 
3675.1.1
by Martin Pool
 Merge and update log+ transport decorator  | 
107  | 
self._trace(('put_bytes', relpath, len(bytes), mode))  | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
108  | 
return self._decorated.put_bytes(relpath, bytes, mode)  | 
109  | 
||
| 
4063.2.1
by Robert Collins
 Teach trace+ to log rmdir and put_bytes_non_atomic calls.  | 
110  | 
def put_bytes_non_atomic(self, relpath, bytes, mode=None,  | 
111  | 
create_parent_dir=False, dir_mode=None):  | 
|
112  | 
"""See Transport.put_bytes_non_atomic."""  | 
|
113  | 
self._trace(('put_bytes_non_atomic', relpath, len(bytes), mode,  | 
|
114  | 
create_parent_dir, dir_mode))  | 
|
115  | 
return self._decorated.put_bytes_non_atomic(relpath, bytes, mode=mode,  | 
|
116  | 
create_parent_dir=create_parent_dir, dir_mode=dir_mode)  | 
|
117  | 
||
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
118  | 
def listable(self):  | 
119  | 
"""See Transport.listable."""  | 
|
120  | 
return self._decorated.listable()  | 
|
121  | 
||
122  | 
def iter_files_recursive(self):  | 
|
123  | 
"""See Transport.iter_files_recursive()."""  | 
|
124  | 
return self._decorated.iter_files_recursive()  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
125  | 
|
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
126  | 
def list_dir(self, relpath):  | 
127  | 
"""See Transport.list_dir()."""  | 
|
128  | 
return self._decorated.list_dir(relpath)  | 
|
129  | 
||
130  | 
def readv(self, relpath, offsets, adjust_for_latency=False,  | 
|
131  | 
upper_limit=None):  | 
|
| 
4491.2.2
by Martin Pool
 TransportLogDecorator.readv must return a generator  | 
132  | 
        # we override at the readv() level rather than _readv() so that any
 | 
133  | 
        # latency adjustments will be done by the underlying transport
 | 
|
| 
3675.1.1
by Martin Pool
 Merge and update log+ transport decorator  | 
134  | 
self._trace(('readv', relpath, offsets, adjust_for_latency,  | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
135  | 
upper_limit))  | 
136  | 
return self._decorated.readv(relpath, offsets, adjust_for_latency,  | 
|
137  | 
upper_limit)  | 
|
138  | 
||
139  | 
def recommended_page_size(self):  | 
|
140  | 
"""See Transport.recommended_page_size()."""  | 
|
141  | 
return self._decorated.recommended_page_size()  | 
|
142  | 
||
143  | 
def rename(self, rel_from, rel_to):  | 
|
| 
3515.3.1
by Robert Collins
 (robertc) More tracing for trace+ transport. (Robert Collins)  | 
144  | 
self._activity.append(('rename', rel_from, rel_to))  | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
145  | 
return self._decorated.rename(rel_from, rel_to)  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
146  | 
|
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
147  | 
def rmdir(self, relpath):  | 
148  | 
"""See Transport.rmdir."""  | 
|
| 
4063.2.1
by Robert Collins
 Teach trace+ to log rmdir and put_bytes_non_atomic calls.  | 
149  | 
self._trace(('rmdir', relpath))  | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
150  | 
return self._decorated.rmdir(relpath)  | 
151  | 
||
152  | 
def stat(self, relpath):  | 
|
153  | 
"""See Transport.stat()."""  | 
|
154  | 
return self._decorated.stat(relpath)  | 
|
155  | 
||
156  | 
def lock_read(self, relpath):  | 
|
157  | 
"""See Transport.lock_read."""  | 
|
158  | 
return self._decorated.lock_read(relpath)  | 
|
159  | 
||
160  | 
def lock_write(self, relpath):  | 
|
161  | 
"""See Transport.lock_write."""  | 
|
162  | 
return self._decorated.lock_write(relpath)  | 
|
163  | 
||
| 
3675.1.1
by Martin Pool
 Merge and update log+ transport decorator  | 
164  | 
def _trace(self, operation_tuple):  | 
165  | 
"""Record that a transport operation occured.  | 
|
166  | 
||
167  | 
        :param operation: Tuple of transport call name and arguments.
 | 
|
168  | 
        """
 | 
|
169  | 
self._activity.append(operation_tuple)  | 
|
170  | 
||
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
171  | 
|
172  | 
class TraceServer(DecoratorServer):  | 
|
173  | 
"""Server for the TransportTraceDecorator for testing with."""  | 
|
174  | 
||
175  | 
def get_decorator_class(self):  | 
|
176  | 
return TransportTraceDecorator  | 
|
177  | 
||
178  | 
||
179  | 
def get_test_permutations():  | 
|
| 
2745.5.4
by Robert Collins
 Review feedback.  | 
180  | 
"""Return the permutations to be used in testing."""  | 
| 
2745.5.3
by Robert Collins
 * Move transport logging into a new transport class  | 
181  | 
return [(TransportTraceDecorator, TraceServer)]  |