/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/matchers.py

  • Committer: Jelmer Vernooij
  • Date: 2018-02-18 21:42:57 UTC
  • mto: This revision was merged to the branch mainline in revision 6859.
  • Revision ID: jelmer@jelmer.uk-20180218214257-jpevutp1wa30tz3v
Update TODO to reference Breezy, not Bazaar.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 
29
29
__all__ = [
30
30
    'HasLayout',
31
 
    'HasPathRelations',
32
31
    'MatchesAncestry',
 
32
    'ContainsNoVfsCalls',
33
33
    'ReturnsUnlockable',
34
34
    'RevisionHistoryMatches',
35
35
    ]
38
38
    osutils,
39
39
    revision as _mod_revision,
40
40
    )
41
 
 
42
 
from ..tree import InterTree
 
41
from .. import lazy_import
 
42
lazy_import.lazy_import(globals(),
 
43
"""
 
44
from breezy.bzr.smart.request import request_handlers as smart_request_handlers
 
45
from breezy.bzr.smart import vfs
 
46
""")
 
47
from ..sixish import (
 
48
    text_type,
 
49
    )
43
50
 
44
51
from testtools.matchers import Equals, Mismatch, Matcher
45
52
 
60
67
 
61
68
    def __str__(self):
62
69
        return ('ReturnsUnlockable(lockable_thing=%s)' %
63
 
                self.lockable_thing)
 
70
            self.lockable_thing)
64
71
 
65
72
    def match(self, lock_method):
66
73
        lock_method().unlock()
116
123
                got.remove(_mod_revision.NULL_REVISION)
117
124
        if sorted(got) != sorted(expected):
118
125
            return _AncestryMismatch(self.revision_id, sorted(got),
119
 
                                     sorted(expected))
 
126
                sorted(expected))
120
127
 
121
128
 
122
129
class HasLayout(Matcher):
129
136
        Matcher.__init__(self)
130
137
        self.entries = entries
131
138
 
132
 
    def get_tree_layout(self, tree, include_file_ids):
 
139
    def get_tree_layout(self, tree):
133
140
        """Get the (path, file_id) pairs for the current tree."""
134
141
        with tree.lock_read():
135
142
            for path, ie in tree.iter_entries_by_dir():
136
 
                if path != u'':
137
 
                    path += ie.kind_character()
138
 
                if include_file_ids:
139
 
                    yield (path, ie.file_id)
 
143
                if ie.parent_id is None:
 
144
                    yield (u"", ie.file_id)
140
145
                else:
141
 
                    yield path
 
146
                    yield (path+ie.kind_character(), ie.file_id)
142
147
 
143
148
    @staticmethod
144
149
    def _strip_unreferenced_directories(entries):
148
153
        """
149
154
        directories = []
150
155
        for entry in entries:
151
 
            if isinstance(entry, str):
 
156
            if isinstance(entry, (str, text_type)):
152
157
                path = entry
153
158
            else:
154
159
                path = entry[0]
167
172
        return 'HasLayout(%r)' % self.entries
168
173
 
169
174
    def match(self, tree):
170
 
        include_file_ids = self.entries and not isinstance(
171
 
            self.entries[0], str)
172
 
        actual = list(self.get_tree_layout(
173
 
            tree, include_file_ids=include_file_ids))
 
175
        actual = list(self.get_tree_layout(tree))
 
176
        if self.entries and isinstance(self.entries[0], (str, text_type)):
 
177
            actual = [path for (path, fileid) in actual]
174
178
        if not tree.has_versioned_directories():
175
179
            entries = list(self._strip_unreferenced_directories(self.entries))
176
180
        else:
178
182
        return Equals(entries).match(actual)
179
183
 
180
184
 
181
 
class HasPathRelations(Matcher):
182
 
    """Matcher verifies that paths have a relation to those in another tree.
183
 
 
184
 
    :ivar previous_tree: tree to compare to
185
 
    :ivar previous_entries: List of expected entries, as (path, previous_path) pairs.
186
 
    """
187
 
 
188
 
    def __init__(self, previous_tree, previous_entries):
189
 
        Matcher.__init__(self)
190
 
        self.previous_tree = previous_tree
191
 
        self.previous_entries = previous_entries
192
 
 
193
 
    def get_path_map(self, tree):
194
 
        """Get the (path, previous_path) pairs for the current tree."""
195
 
        previous_intertree = InterTree.get(self.previous_tree, tree)
196
 
        with tree.lock_read(), self.previous_tree.lock_read():
197
 
            for path, ie in tree.iter_entries_by_dir():
198
 
                if tree.supports_rename_tracking():
199
 
                    previous_path = previous_intertree.find_source_path(path)
200
 
                else:
201
 
                    if self.previous_tree.is_versioned(path):
202
 
                        previous_path = path
203
 
                    else:
204
 
                        previous_path = None
205
 
                if previous_path:
206
 
                    kind = self.previous_tree.kind(previous_path)
207
 
                    if kind == 'directory':
208
 
                        previous_path += '/'
209
 
                if path == u'':
210
 
                    yield (u"", previous_path)
211
 
                else:
212
 
                    yield (path + ie.kind_character(), previous_path)
213
 
 
214
 
    @staticmethod
215
 
    def _strip_unreferenced_directories(entries):
216
 
        """Strip all directories that don't (in)directly contain any files.
217
 
 
218
 
        :param entries: List of path strings or (path, previous_path) tuples to process
219
 
        """
220
 
        directory_used = set()
221
 
        directories = []
222
 
        for (path, previous_path) in entries:
223
 
            if not path or path[-1] == "/":
224
 
                # directory
225
 
                directories.append((path, previous_path))
226
 
            else:
227
 
                # Yield the referenced parent directories
228
 
                for direntry in directories:
229
 
                    if osutils.is_inside(direntry[0], path):
230
 
                        directory_used.add(direntry[0])
231
 
        for (path, previous_path) in entries:
232
 
            if (not path.endswith("/")) or path in directory_used:
233
 
                yield (path, previous_path)
234
 
 
235
 
    def __str__(self):
236
 
        return 'HasPathRelations(%r, %r)' % (self.previous_tree, self.previous_entries)
237
 
 
238
 
    def match(self, tree):
239
 
        actual = list(self.get_path_map(tree))
240
 
        if not tree.has_versioned_directories():
241
 
            entries = list(self._strip_unreferenced_directories(
242
 
                self.previous_entries))
243
 
        else:
244
 
            entries = self.previous_entries
245
 
        if not tree.supports_rename_tracking():
246
 
            entries = [
247
 
                (path, path if self.previous_tree.is_versioned(path) else None)
248
 
                for (path, previous_path) in entries]
249
 
        return Equals(entries).match(actual)
250
 
 
251
 
 
252
185
class RevisionHistoryMatches(Matcher):
253
186
    """A matcher that checks if a branch has a specific revision history.
254
187
 
269
202
                branch.last_revision(), [_mod_revision.NULL_REVISION]))
270
203
            history.reverse()
271
204
        return Equals(self.expected).match(history)
 
205
 
 
206
 
 
207
class _NoVfsCallsMismatch(Mismatch):
 
208
    """Mismatch describing a list of HPSS calls which includes VFS requests."""
 
209
 
 
210
    def __init__(self, vfs_calls):
 
211
        self.vfs_calls = vfs_calls
 
212
 
 
213
    def describe(self):
 
214
        return "no VFS calls expected, got: %s" % ",".join([
 
215
            "%s(%s)" % (c.method,
 
216
                ", ".join([repr(a) for a in c.args])) for c in self.vfs_calls])
 
217
 
 
218
 
 
219
class ContainsNoVfsCalls(Matcher):
 
220
    """Ensure that none of the specified calls are HPSS calls."""
 
221
 
 
222
    def __str__(self):
 
223
        return 'ContainsNoVfsCalls()'
 
224
 
 
225
    @classmethod
 
226
    def match(cls, hpss_calls):
 
227
        vfs_calls = []
 
228
        for call in hpss_calls:
 
229
            try:
 
230
                request_method = smart_request_handlers.get(call.call.method)
 
231
            except KeyError:
 
232
                # A method we don't know about doesn't count as a VFS method.
 
233
                continue
 
234
            if issubclass(request_method, vfs.VfsRequest):
 
235
                vfs_calls.append(call.call)
 
236
        if len(vfs_calls) == 0:
 
237
            return None
 
238
        return _NoVfsCallsMismatch(vfs_calls)