bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
1 |
# Copyright (C) 2007-2011 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
|
|
15 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
16 |
||
|
6624
by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes') |
17 |
from .. import ( |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
18 |
graph as _mod_graph, |
19 |
tests, |
|
|
6670.4.1
by Jelmer Vernooij
Update imports. |
20 |
)
|
21 |
from ..bzr import ( |
|
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
22 |
vf_search, |
23 |
)
|
|
|
6624
by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes') |
24 |
from ..revision import NULL_REVISION |
25 |
from .test_graph import TestGraphBase |
|
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
26 |
|
|
6341.1.4
by Jelmer Vernooij
Move more functionality to vf_search. |
27 |
# Ancestry 1:
|
28 |
#
|
|
29 |
# NULL_REVISION
|
|
30 |
# |
|
|
31 |
# rev1
|
|
32 |
# /\
|
|
33 |
# rev2a rev2b
|
|
34 |
# | |
|
|
35 |
# rev3 /
|
|
36 |
# | /
|
|
37 |
# rev4
|
|
38 |
ancestry_1 = {'rev1': [NULL_REVISION], 'rev2a': ['rev1'], 'rev2b': ['rev1'], |
|
39 |
'rev3': ['rev2a'], 'rev4': ['rev3', 'rev2b']} |
|
40 |
||
41 |
# Ancestry 2:
|
|
42 |
#
|
|
43 |
# NULL_REVISION
|
|
44 |
# / \
|
|
45 |
# rev1a rev1b
|
|
46 |
# |
|
|
47 |
# rev2a
|
|
48 |
# |
|
|
49 |
# rev3a
|
|
50 |
# |
|
|
51 |
# rev4a
|
|
52 |
ancestry_2 = {'rev1a': [NULL_REVISION], 'rev2a': ['rev1a'], |
|
53 |
'rev1b': [NULL_REVISION], 'rev3a': ['rev2a'], 'rev4a': ['rev3a']} |
|
54 |
||
55 |
||
56 |
# Extended history shortcut
|
|
57 |
# NULL_REVISION
|
|
58 |
# |
|
|
59 |
# a
|
|
60 |
# |\
|
|
61 |
# b |
|
|
62 |
# | |
|
|
63 |
# c |
|
|
64 |
# | |
|
|
65 |
# d |
|
|
66 |
# |\|
|
|
67 |
# e f
|
|
68 |
extended_history_shortcut = {'a': [NULL_REVISION], |
|
69 |
'b': ['a'], |
|
70 |
'c': ['b'], |
|
71 |
'd': ['c'], |
|
72 |
'e': ['d'], |
|
73 |
'f': ['a', 'd'], |
|
74 |
}
|
|
75 |
||
76 |
||
77 |
class TestSearchResultRefine(tests.TestCase): |
|
78 |
||
79 |
def make_graph(self, ancestors): |
|
80 |
return _mod_graph.Graph(_mod_graph.DictParentsProvider(ancestors)) |
|
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
81 |
|
82 |
def test_refine(self): |
|
83 |
# Used when pulling from a stacked repository, so test some revisions
|
|
84 |
# being satisfied from the stacking branch.
|
|
85 |
g = self.make_graph( |
|
86 |
{"tip":["mid"], "mid":["base"], "tag":["base"], |
|
87 |
"base":[NULL_REVISION], NULL_REVISION:[]}) |
|
|
6619.3.12
by Jelmer Vernooij
Use 2to3 set_literal fixer. |
88 |
result = vf_search.SearchResult({'tip', 'tag'}, |
89 |
{NULL_REVISION}, 4, {'tip', 'mid', 'tag', 'base'}) |
|
90 |
result = result.refine({'tip'}, {'mid'}) |
|
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
91 |
recipe = result.get_recipe() |
92 |
# We should be starting from tag (original head) and mid (seen ref)
|
|
|
6619.3.12
by Jelmer Vernooij
Use 2to3 set_literal fixer. |
93 |
self.assertEqual({'mid', 'tag'}, recipe[1]) |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
94 |
# We should be stopping at NULL (original stop) and tip (seen head)
|
|
6619.3.12
by Jelmer Vernooij
Use 2to3 set_literal fixer. |
95 |
self.assertEqual({NULL_REVISION, 'tip'}, recipe[2]) |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
96 |
self.assertEqual(3, recipe[3]) |
|
6619.3.12
by Jelmer Vernooij
Use 2to3 set_literal fixer. |
97 |
result = result.refine({'mid', 'tag', 'base'}, |
98 |
{NULL_REVISION}) |
|
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
99 |
recipe = result.get_recipe() |
100 |
# We should be starting from nothing (NULL was known as a cut point)
|
|
101 |
self.assertEqual(set([]), recipe[1]) |
|
102 |
# We should be stopping at NULL (original stop) and tip (seen head) and
|
|
103 |
# tag (seen head) and mid(seen mid-point head). We could come back and
|
|
104 |
# define this as not including mid, for minimal results, but it is
|
|
105 |
# still 'correct' to include mid, and simpler/easier.
|
|
|
6619.3.12
by Jelmer Vernooij
Use 2to3 set_literal fixer. |
106 |
self.assertEqual({NULL_REVISION, 'tip', 'tag', 'mid'}, recipe[2]) |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
107 |
self.assertEqual(0, recipe[3]) |
108 |
self.assertTrue(result.is_empty()) |
|
109 |
||
110 |
||
111 |
class TestSearchResultFromParentMap(TestGraphBase): |
|
112 |
||
113 |
def assertSearchResult(self, start_keys, stop_keys, key_count, parent_map, |
|
114 |
missing_keys=()): |
|
|
6341.1.4
by Jelmer Vernooij
Move more functionality to vf_search. |
115 |
(start, stop, count) = vf_search.search_result_from_parent_map( |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
116 |
parent_map, missing_keys) |
117 |
self.assertEqual((sorted(start_keys), sorted(stop_keys), key_count), |
|
118 |
(sorted(start), sorted(stop), count)) |
|
119 |
||
120 |
def test_no_parents(self): |
|
121 |
self.assertSearchResult([], [], 0, {}) |
|
122 |
self.assertSearchResult([], [], 0, None) |
|
123 |
||
124 |
def test_ancestry_1(self): |
|
125 |
self.assertSearchResult(['rev4'], [NULL_REVISION], len(ancestry_1), |
|
126 |
ancestry_1) |
|
127 |
||
128 |
def test_ancestry_2(self): |
|
129 |
self.assertSearchResult(['rev1b', 'rev4a'], [NULL_REVISION], |
|
130 |
len(ancestry_2), ancestry_2) |
|
131 |
self.assertSearchResult(['rev1b', 'rev4a'], [], |
|
132 |
len(ancestry_2)+1, ancestry_2, |
|
133 |
missing_keys=[NULL_REVISION]) |
|
134 |
||
135 |
def test_partial_search(self): |
|
136 |
parent_map = dict((k,extended_history_shortcut[k]) |
|
137 |
for k in ['e', 'f']) |
|
138 |
self.assertSearchResult(['e', 'f'], ['d', 'a'], 2, |
|
139 |
parent_map) |
|
140 |
parent_map.update((k,extended_history_shortcut[k]) |
|
141 |
for k in ['d', 'a']) |
|
142 |
self.assertSearchResult(['e', 'f'], ['c', NULL_REVISION], 4, |
|
143 |
parent_map) |
|
144 |
parent_map['c'] = extended_history_shortcut['c'] |
|
145 |
self.assertSearchResult(['e', 'f'], ['b'], 6, |
|
146 |
parent_map, missing_keys=[NULL_REVISION]) |
|
147 |
parent_map['b'] = extended_history_shortcut['b'] |
|
148 |
self.assertSearchResult(['e', 'f'], [], 7, |
|
149 |
parent_map, missing_keys=[NULL_REVISION]) |
|
150 |
||
151 |
||
152 |
class TestLimitedSearchResultFromParentMap(TestGraphBase): |
|
153 |
||
154 |
def assertSearchResult(self, start_keys, stop_keys, key_count, parent_map, |
|
155 |
missing_keys, tip_keys, depth): |
|
|
6341.1.4
by Jelmer Vernooij
Move more functionality to vf_search. |
156 |
(start, stop, count) = vf_search.limited_search_result_from_parent_map( |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
157 |
parent_map, missing_keys, tip_keys, depth) |
158 |
self.assertEqual((sorted(start_keys), sorted(stop_keys), key_count), |
|
159 |
(sorted(start), sorted(stop), count)) |
|
160 |
||
161 |
def test_empty_ancestry(self): |
|
162 |
self.assertSearchResult([], [], 0, {}, (), ['tip-rev-id'], 10) |
|
163 |
||
164 |
def test_ancestry_1(self): |
|
165 |
self.assertSearchResult(['rev4'], ['rev1'], 4, |
|
166 |
ancestry_1, (), ['rev1'], 10) |
|
167 |
self.assertSearchResult(['rev2a', 'rev2b'], ['rev1'], 2, |
|
168 |
ancestry_1, (), ['rev1'], 1) |
|
169 |
||
170 |
||
171 |
def test_multiple_heads(self): |
|
172 |
self.assertSearchResult(['e', 'f'], ['a'], 5, |
|
173 |
extended_history_shortcut, (), ['a'], 10) |
|
174 |
# Note that even though we only take 1 step back, we find 'f', which
|
|
175 |
# means the described search will still find d and c.
|
|
176 |
self.assertSearchResult(['f'], ['a'], 4, |
|
177 |
extended_history_shortcut, (), ['a'], 1) |
|
178 |
self.assertSearchResult(['f'], ['a'], 4, |
|
179 |
extended_history_shortcut, (), ['a'], 2) |
|
180 |
||
181 |
||
|
6341.1.4
by Jelmer Vernooij
Move more functionality to vf_search. |
182 |
class TestPendingAncestryResultRefine(tests.TestCase): |
183 |
||
184 |
def make_graph(self, ancestors): |
|
185 |
return _mod_graph.Graph(_mod_graph.DictParentsProvider(ancestors)) |
|
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
186 |
|
187 |
def test_refine(self): |
|
188 |
# Used when pulling from a stacked repository, so test some revisions
|
|
189 |
# being satisfied from the stacking branch.
|
|
190 |
g = self.make_graph( |
|
191 |
{"tip":["mid"], "mid":["base"], "tag":["base"], |
|
192 |
"base":[NULL_REVISION], NULL_REVISION:[]}) |
|
|
6341.1.4
by Jelmer Vernooij
Move more functionality to vf_search. |
193 |
result = vf_search.PendingAncestryResult(['tip', 'tag'], None) |
|
6619.3.12
by Jelmer Vernooij
Use 2to3 set_literal fixer. |
194 |
result = result.refine({'tip'}, {'mid'}) |
195 |
self.assertEqual({'mid', 'tag'}, result.heads) |
|
196 |
result = result.refine({'mid', 'tag', 'base'}, |
|
197 |
{NULL_REVISION}) |
|
198 |
self.assertEqual({NULL_REVISION}, result.heads) |
|
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
199 |
self.assertTrue(result.is_empty()) |
200 |
||
201 |
||
202 |
class TestPendingAncestryResultGetKeys(tests.TestCaseWithMemoryTransport): |
|
|
6622.1.34
by Jelmer Vernooij
Rename brzlib => breezy. |
203 |
"""Tests for breezy.graph.PendingAncestryResult.""" |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
204 |
|
205 |
def test_get_keys(self): |
|
206 |
builder = self.make_branch_builder('b') |
|
207 |
builder.start_series() |
|
208 |
builder.build_snapshot('rev-1', None, [ |
|
209 |
('add', ('', 'root-id', 'directory', ''))]) |
|
210 |
builder.build_snapshot('rev-2', ['rev-1'], []) |
|
211 |
builder.finish_series() |
|
212 |
repo = builder.get_branch().repository |
|
213 |
repo.lock_read() |
|
214 |
self.addCleanup(repo.unlock) |
|
|
6341.1.4
by Jelmer Vernooij
Move more functionality to vf_search. |
215 |
result = vf_search.PendingAncestryResult(['rev-2'], repo) |
|
6619.3.12
by Jelmer Vernooij
Use 2to3 set_literal fixer. |
216 |
self.assertEqual({'rev-1', 'rev-2'}, set(result.get_keys())) |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
217 |
|
218 |
def test_get_keys_excludes_ghosts(self): |
|
219 |
builder = self.make_branch_builder('b') |
|
220 |
builder.start_series() |
|
221 |
builder.build_snapshot('rev-1', None, [ |
|
222 |
('add', ('', 'root-id', 'directory', ''))]) |
|
223 |
builder.build_snapshot('rev-2', ['rev-1', 'ghost'], []) |
|
224 |
builder.finish_series() |
|
225 |
repo = builder.get_branch().repository |
|
226 |
repo.lock_read() |
|
227 |
self.addCleanup(repo.unlock) |
|
|
6341.1.4
by Jelmer Vernooij
Move more functionality to vf_search. |
228 |
result = vf_search.PendingAncestryResult(['rev-2'], repo) |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
229 |
self.assertEqual(sorted(['rev-1', 'rev-2']), sorted(result.get_keys())) |
230 |
||
231 |
def test_get_keys_excludes_null(self): |
|
232 |
# Make a 'graph' with an iter_ancestry that returns NULL_REVISION
|
|
233 |
# somewhere other than the last element, which can happen in real
|
|
234 |
# ancestries.
|
|
235 |
class StubGraph(object): |
|
236 |
def iter_ancestry(self, keys): |
|
237 |
return [(NULL_REVISION, ()), ('foo', (NULL_REVISION,))] |
|
|
6341.1.4
by Jelmer Vernooij
Move more functionality to vf_search. |
238 |
result = vf_search.PendingAncestryResult(['rev-3'], None) |
|
6341.1.3
by Jelmer Vernooij
Move search result code to vf_search module. |
239 |
result_keys = result._get_keys(StubGraph()) |
240 |
# Only the non-null keys from the ancestry appear.
|
|
|
6619.3.12
by Jelmer Vernooij
Use 2to3 set_literal fixer. |
241 |
self.assertEqual({'foo'}, set(result_keys)) |