41
41
builder = self.make_branch_builder('branch')
42
42
builder.start_series()
43
builder.build_snapshot('rev-1', None, [
44
('add', ('', 'root-id', 'directory', None))])
45
builder.build_snapshot('rev-2', ['rev-1'], [])
46
builder.build_snapshot('rev-3', ['rev-2'], [])
43
rev1 = builder.build_snapshot(None, [
44
('add', ('', b'root-id', 'directory', None))])
45
rev2 = builder.build_snapshot([rev1], [])
46
rev3 = builder.build_snapshot([rev2], [])
47
47
builder.finish_series()
48
48
b = builder.get_branch()
49
49
self.addCleanup(b.lock_read().unlock)
50
return _mod_history.History(b, {})
50
return _mod_history.History(b, {}), [rev1, rev2, rev3]
52
52
def make_long_linear_ancestry(self):
53
53
builder = self.make_branch_builder('branch')
54
55
builder.start_series()
55
builder.build_snapshot('A', None, [
56
('add', ('', 'root-id', 'directory', None))])
56
revs.append(builder.build_snapshot(None, [
57
('add', ('', b'root-id', 'directory', None))]))
57
58
for r in "BCDEFGHIJKLMNOPQRSTUVWXYZ":
58
builder.build_snapshot(r, None, [])
59
revs.append(builder.build_snapshot(None, []))
59
60
builder.finish_series()
60
61
b = builder.get_branch()
61
62
self.addCleanup(b.lock_read().unlock)
62
return _mod_history.History(b, {})
63
return _mod_history.History(b, {}), revs
64
65
def make_merged_ancestry(self):
71
72
builder = self.make_branch_builder('branch')
72
73
builder.start_series()
73
builder.build_snapshot('rev-1', None, [
74
('add', ('', 'root-id', 'directory', None))])
75
builder.build_snapshot('rev-2', ['rev-1'], [])
76
builder.build_snapshot('rev-3', ['rev-1', 'rev-2'], [])
74
rev1 = builder.build_snapshot(None, [
75
('add', ('', b'root-id', 'directory', None))])
76
rev2 = builder.build_snapshot([rev1], [])
77
rev3 = builder.build_snapshot([rev1, rev2], [])
77
78
builder.finish_series()
78
79
b = builder.get_branch()
79
80
self.addCleanup(b.lock_read().unlock)
80
return _mod_history.History(b, {})
81
return _mod_history.History(b, {}), [rev1, rev2, rev3]
82
83
def make_deep_merged_ancestry(self):
93
94
builder = self.make_branch_builder('branch')
94
95
builder.start_series()
95
builder.build_snapshot('A', None, [
96
('add', ('', 'root-id', 'directory', None))])
97
builder.build_snapshot('B', ['A'], [])
98
builder.build_snapshot('C', ['A'], [])
99
builder.build_snapshot('D', ['C'], [])
100
builder.build_snapshot('E', ['C', 'D'], [])
101
builder.build_snapshot('F', ['B', 'E'], [])
96
rev_a = builder.build_snapshot(None, [
97
('add', ('', b'root-id', 'directory', None))])
98
rev_b = builder.build_snapshot([rev_a], [])
99
rev_c = builder.build_snapshot([rev_a], [])
100
rev_d = builder.build_snapshot([rev_c], [])
101
rev_e = builder.build_snapshot([rev_c, rev_d], [])
102
rev_f = builder.build_snapshot([rev_b, rev_e], [])
102
103
builder.finish_series()
103
104
b = builder.get_branch()
104
105
self.addCleanup(b.lock_read().unlock)
105
return _mod_history.History(b, {})
106
return (_mod_history.History(b, {}),
107
[rev_a, rev_b, rev_c, rev_d, rev_e, rev_f])
107
109
def assertRevidsFrom(self, expected, history, search_revs, tip_rev):
108
110
self.assertEqual(expected,
136
138
class TestHistoryGetRevidsFrom(TestCaseWithExamples):
138
140
def test_get_revids_from_simple_mainline(self):
139
history = self.make_linear_ancestry()
140
self.assertRevidsFrom(['rev-3', 'rev-2', 'rev-1'],
141
history, None, 'rev-3')
141
history, revs = self.make_linear_ancestry()
142
self.assertRevidsFrom(list(reversed(revs)), history, None, revs[2])
143
144
def test_get_revids_from_merged_mainline(self):
144
history = self.make_merged_ancestry()
145
self.assertRevidsFrom(['rev-3', 'rev-1'],
146
history, None, 'rev-3')
145
history, revs = self.make_merged_ancestry()
146
self.assertRevidsFrom([revs[2], revs[0]],
147
history, None, revs[2])
148
149
def test_get_revids_given_one_rev(self):
149
history = self.make_merged_ancestry()
150
history, revs = self.make_merged_ancestry()
150
151
# rev-3 was the first mainline revision to see rev-2.
151
self.assertRevidsFrom(['rev-3'], history, ['rev-2'], 'rev-3')
152
self.assertRevidsFrom([revs[2]], history, [revs[1]], revs[2])
153
154
def test_get_revids_deep_ancestry(self):
154
history = self.make_deep_merged_ancestry()
155
self.assertRevidsFrom(['F'], history, ['F'], 'F')
156
self.assertRevidsFrom(['F'], history, ['E'], 'F')
157
self.assertRevidsFrom(['F'], history, ['D'], 'F')
158
self.assertRevidsFrom(['F'], history, ['C'], 'F')
159
self.assertRevidsFrom(['B'], history, ['B'], 'F')
160
self.assertRevidsFrom(['A'], history, ['A'], 'F')
155
history, revs = self.make_deep_merged_ancestry()
156
self.assertRevidsFrom([revs[-1]], history, [revs[-1]], revs[-1])
157
self.assertRevidsFrom([revs[-1]], history, [revs[-2]], revs[-1])
158
self.assertRevidsFrom([revs[-1]], history, [revs[-3]], revs[-1])
159
self.assertRevidsFrom([revs[-1]], history, [revs[-4]], revs[-1])
160
self.assertRevidsFrom([revs[1]], history, [revs[-5]], revs[-1])
161
self.assertRevidsFrom([revs[0]], history, [revs[-6]], revs[-1])
162
163
def test_get_revids_doesnt_over_produce_simple_mainline(self):
163
164
# get_revids_from shouldn't walk the whole ancestry just to get the
164
165
# answers for the first few revisions.
165
history = self.make_long_linear_ancestry()
166
history, revs = self.make_long_linear_ancestry()
166
167
accessed = track_rev_info_accesses(history)
167
result = history.get_revids_from(None, 'Z')
168
self.assertEqual(set(), accessed)
169
self.assertEqual('Z', result.next())
170
# We already know 'Z' because we passed it in.
171
self.assertEqual(set(), accessed)
172
self.assertEqual('Y', result.next())
173
self.assertEqual(set([history._rev_indices['Z']]), accessed)
168
result = history.get_revids_from(None, revs[-1])
169
self.assertEqual(set(), accessed)
170
self.assertEqual(revs[-1], next(result))
171
# We already know revs[-1] because we passed it in.
172
self.assertEqual(set(), accessed)
173
self.assertEqual(revs[-2], next(result))
174
self.assertEqual(set([history._rev_indices[revs[-1]]]), accessed)
175
176
def test_get_revids_doesnt_over_produce_for_merges(self):
176
177
# get_revids_from shouldn't walk the whole ancestry just to get the
177
178
# answers for the first few revisions.
178
history = self.make_long_linear_ancestry()
179
history, revs = self.make_long_linear_ancestry()
179
180
accessed = track_rev_info_accesses(history)
180
result = history.get_revids_from(['X', 'V'], 'Z')
181
result = history.get_revids_from([revs[-3], revs[-5]], revs[-1])
181
182
self.assertEqual(set(), accessed)
182
self.assertEqual('X', result.next())
183
self.assertEqual(revs[-3], next(result))
183
184
# We access 'W' because we are checking that W wasn't merged into X.
184
185
# The important bit is that we aren't getting the whole ancestry.
185
self.assertEqual(set([history._rev_indices[x] for x in 'ZYXW']),
187
self.assertEqual('V', result.next())
188
self.assertEqual(set([history._rev_indices[x] for x in 'ZYXWVU']),
190
self.assertRaises(StopIteration, result.next)
191
self.assertEqual(set([history._rev_indices[x] for x in 'ZYXWVU']),
186
self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:4]]),
188
self.assertEqual(revs[-5], next(result))
189
self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:6]]),
191
self.assertRaises(StopIteration, next, result)
192
self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:6]]),
291
292
def test_get_view_limited_history(self):
292
293
# get_view should only load enough history to serve the result, not all
294
history = self.make_long_linear_ancestry()
295
history, revs = self.make_long_linear_ancestry()
295
296
accessed = track_rev_info_accesses(history)
296
revid, start_revid, revid_list = history.get_view('Z', 'Z', None,
297
revid, start_revid, revid_list = history.get_view(revs[-1], revs[-1], None,
297
298
extra_rev_count=5)
298
self.assertEqual(['Z', 'Y', 'X', 'W', 'V', 'U'], revid_list)
299
self.assertEqual('Z', revid)
300
self.assertEqual('Z', start_revid)
301
self.assertEqual(set([history._rev_indices[x] for x in 'ZYXWVU']),
299
self.assertEqual(list(reversed(revs))[:6], revid_list)
300
self.assertEqual(revs[-1], revid)
301
self.assertEqual(revs[-1], start_revid)
302
self.assertEqual(set([history._rev_indices[x] for x in list(reversed(revs))[:6]]),
305
306
class TestHistoryGetChangedUncached(TestCaseWithExamples):
307
308
def test_native(self):
308
history = self.make_linear_ancestry()
309
changes = history.get_changes_uncached(['rev-1', 'rev-2'])
309
history, revs = self.make_linear_ancestry()
310
changes = history.get_changes_uncached([revs[0], revs[1]])
310
311
self.assertEquals(2, len(changes))
311
self.assertEquals('rev-1', changes[0].revid)
312
self.assertEquals('rev-2', changes[1].revid)
312
self.assertEquals(revs[0], changes[0].revid)
313
self.assertEquals(revs[1], changes[1].revid)
313
314
self.assertIs(None, getattr(changes[0], 'foreign_vcs', None))
314
315
self.assertIs(None, getattr(changes[0], 'foreign_revid', None))
316
317
def test_foreign(self):
317
318
# Test with a mocked foreign revision, as it's not possible
318
319
# to rely on any foreign plugins being installed.
319
history = self.make_linear_ancestry()
320
history, revs = self.make_linear_ancestry()
320
321
foreign_vcs = ForeignVcs(None, "vcs")
321
322
foreign_vcs.show_foreign_revid = repr
322
323
foreign_rev = ForeignRevision(("uuid", 1234), VcsMapping(foreign_vcs),