87
87
def test_children_ancestry1(self):
88
88
graph = self.make_known_graph(test_graph.ancestry_1)
89
self.assertEqual([b'rev1'], graph.get_child_keys(NULL_REVISION))
90
self.assertEqual([b'rev2a', b'rev2b'],
91
sorted(graph.get_child_keys(b'rev1')))
92
self.assertEqual([b'rev3'], graph.get_child_keys(b'rev2a'))
93
self.assertEqual([b'rev4'], graph.get_child_keys(b'rev3'))
94
self.assertEqual([b'rev4'], graph.get_child_keys(b'rev2b'))
95
self.assertRaises(KeyError, graph.get_child_keys, b'not_in_graph')
89
self.assertEqual(['rev1'], graph.get_child_keys(NULL_REVISION))
90
self.assertEqual(['rev2a', 'rev2b'],
91
sorted(graph.get_child_keys('rev1')))
92
self.assertEqual(['rev3'], graph.get_child_keys('rev2a'))
93
self.assertEqual(['rev4'], graph.get_child_keys('rev3'))
94
self.assertEqual(['rev4'], graph.get_child_keys('rev2b'))
95
self.assertRaises(KeyError, graph.get_child_keys, 'not_in_graph')
97
97
def test_parent_ancestry1(self):
98
98
graph = self.make_known_graph(test_graph.ancestry_1)
99
self.assertEqual([NULL_REVISION], graph.get_parent_keys(b'rev1'))
100
self.assertEqual([b'rev1'], graph.get_parent_keys(b'rev2a'))
101
self.assertEqual([b'rev1'], graph.get_parent_keys(b'rev2b'))
102
self.assertEqual([b'rev2a'], graph.get_parent_keys(b'rev3'))
103
self.assertEqual([b'rev2b', b'rev3'],
104
sorted(graph.get_parent_keys(b'rev4')))
105
self.assertRaises(KeyError, graph.get_child_keys, b'not_in_graph')
99
self.assertEqual([NULL_REVISION], graph.get_parent_keys('rev1'))
100
self.assertEqual(['rev1'], graph.get_parent_keys('rev2a'))
101
self.assertEqual(['rev1'], graph.get_parent_keys('rev2b'))
102
self.assertEqual(['rev2a'], graph.get_parent_keys('rev3'))
103
self.assertEqual(['rev2b', 'rev3'],
104
sorted(graph.get_parent_keys('rev4')))
105
self.assertRaises(KeyError, graph.get_child_keys, 'not_in_graph')
107
107
def test_parent_with_ghost(self):
108
108
graph = self.make_known_graph(test_graph.with_ghost)
109
self.assertEqual(None, graph.get_parent_keys(b'g'))
109
self.assertEqual(None, graph.get_parent_keys('g'))
111
111
def test_gdfo_ancestry_1(self):
112
112
graph = self.make_known_graph(test_graph.ancestry_1)
113
self.assertGDFO(graph, b'rev1', 2)
114
self.assertGDFO(graph, b'rev2b', 3)
115
self.assertGDFO(graph, b'rev2a', 3)
116
self.assertGDFO(graph, b'rev3', 4)
117
self.assertGDFO(graph, b'rev4', 5)
113
self.assertGDFO(graph, 'rev1', 2)
114
self.assertGDFO(graph, 'rev2b', 3)
115
self.assertGDFO(graph, 'rev2a', 3)
116
self.assertGDFO(graph, 'rev3', 4)
117
self.assertGDFO(graph, 'rev4', 5)
119
119
def test_gdfo_feature_branch(self):
120
120
graph = self.make_known_graph(test_graph.feature_branch)
121
self.assertGDFO(graph, b'rev1', 2)
122
self.assertGDFO(graph, b'rev2b', 3)
123
self.assertGDFO(graph, b'rev3b', 4)
121
self.assertGDFO(graph, 'rev1', 2)
122
self.assertGDFO(graph, 'rev2b', 3)
123
self.assertGDFO(graph, 'rev3b', 4)
125
125
def test_gdfo_extended_history_shortcut(self):
126
126
graph = self.make_known_graph(test_graph.extended_history_shortcut)
127
self.assertGDFO(graph, b'a', 2)
128
self.assertGDFO(graph, b'b', 3)
129
self.assertGDFO(graph, b'c', 4)
130
self.assertGDFO(graph, b'd', 5)
131
self.assertGDFO(graph, b'e', 6)
132
self.assertGDFO(graph, b'f', 6)
127
self.assertGDFO(graph, 'a', 2)
128
self.assertGDFO(graph, 'b', 3)
129
self.assertGDFO(graph, 'c', 4)
130
self.assertGDFO(graph, 'd', 5)
131
self.assertGDFO(graph, 'e', 6)
132
self.assertGDFO(graph, 'f', 6)
134
134
def test_gdfo_with_ghost(self):
135
135
graph = self.make_known_graph(test_graph.with_ghost)
136
self.assertGDFO(graph, b'f', 2)
137
self.assertGDFO(graph, b'e', 3)
138
self.assertGDFO(graph, b'g', 1)
139
self.assertGDFO(graph, b'b', 4)
140
self.assertGDFO(graph, b'd', 4)
141
self.assertGDFO(graph, b'a', 5)
142
self.assertGDFO(graph, b'c', 5)
136
self.assertGDFO(graph, 'f', 2)
137
self.assertGDFO(graph, 'e', 3)
138
self.assertGDFO(graph, 'g', 1)
139
self.assertGDFO(graph, 'b', 4)
140
self.assertGDFO(graph, 'd', 4)
141
self.assertGDFO(graph, 'a', 5)
142
self.assertGDFO(graph, 'c', 5)
144
144
def test_add_existing_node(self):
145
145
graph = self.make_known_graph(test_graph.ancestry_1)
146
146
# Add a node that already exists with identical content
147
147
# This is a 'no-op'
148
self.assertGDFO(graph, b'rev4', 5)
149
graph.add_node(b'rev4', [b'rev3', b'rev2b'])
150
self.assertGDFO(graph, b'rev4', 5)
148
self.assertGDFO(graph, 'rev4', 5)
149
graph.add_node('rev4', ['rev3', 'rev2b'])
150
self.assertGDFO(graph, 'rev4', 5)
151
151
# This also works if we use a tuple rather than a list
152
graph.add_node(b'rev4', (b'rev3', b'rev2b'))
152
graph.add_node('rev4', ('rev3', 'rev2b'))
154
154
def test_add_existing_node_mismatched_parents(self):
155
155
graph = self.make_known_graph(test_graph.ancestry_1)
156
self.assertRaises(ValueError, graph.add_node, b'rev4',
156
self.assertRaises(ValueError, graph.add_node, 'rev4',
159
159
def test_add_node_with_ghost_parent(self):
160
160
graph = self.make_known_graph(test_graph.ancestry_1)
161
graph.add_node(b'rev5', [b'rev2b', b'revGhost'])
162
self.assertGDFO(graph, b'rev5', 4)
163
self.assertGDFO(graph, b'revGhost', 1)
161
graph.add_node('rev5', ['rev2b', 'revGhost'])
162
self.assertGDFO(graph, 'rev5', 4)
163
self.assertGDFO(graph, 'revGhost', 1)
165
165
def test_add_new_root(self):
166
166
graph = self.make_known_graph(test_graph.ancestry_1)
167
graph.add_node(b'rev5', [])
168
self.assertGDFO(graph, b'rev5', 1)
167
graph.add_node('rev5', [])
168
self.assertGDFO(graph, 'rev5', 1)
170
170
def test_add_with_all_ghost_parents(self):
171
171
graph = self.make_known_graph(test_graph.ancestry_1)
172
graph.add_node(b'rev5', [b'ghost'])
173
self.assertGDFO(graph, b'rev5', 2)
174
self.assertGDFO(graph, b'ghost', 1)
172
graph.add_node('rev5', ['ghost'])
173
self.assertGDFO(graph, 'rev5', 2)
174
self.assertGDFO(graph, 'ghost', 1)
176
176
def test_gdfo_after_add_node(self):
177
177
graph = self.make_known_graph(test_graph.ancestry_1)
178
self.assertEqual([], graph.get_child_keys(b'rev4'))
179
graph.add_node(b'rev5', [b'rev4'])
180
self.assertEqual([b'rev4'], graph.get_parent_keys(b'rev5'))
181
self.assertEqual([b'rev5'], graph.get_child_keys(b'rev4'))
182
self.assertEqual([], graph.get_child_keys(b'rev5'))
183
self.assertGDFO(graph, b'rev5', 6)
184
graph.add_node(b'rev6', [b'rev2b'])
185
graph.add_node(b'rev7', [b'rev6'])
186
graph.add_node(b'rev8', [b'rev7', b'rev5'])
187
self.assertGDFO(graph, b'rev5', 6)
188
self.assertGDFO(graph, b'rev6', 4)
189
self.assertGDFO(graph, b'rev7', 5)
190
self.assertGDFO(graph, b'rev8', 7)
178
self.assertEqual([], graph.get_child_keys('rev4'))
179
graph.add_node('rev5', ['rev4'])
180
self.assertEqual(['rev4'], graph.get_parent_keys('rev5'))
181
self.assertEqual(['rev5'], graph.get_child_keys('rev4'))
182
self.assertEqual([], graph.get_child_keys('rev5'))
183
self.assertGDFO(graph, 'rev5', 6)
184
graph.add_node('rev6', ['rev2b'])
185
graph.add_node('rev7', ['rev6'])
186
graph.add_node('rev8', ['rev7', 'rev5'])
187
self.assertGDFO(graph, 'rev5', 6)
188
self.assertGDFO(graph, 'rev6', 4)
189
self.assertGDFO(graph, 'rev7', 5)
190
self.assertGDFO(graph, 'rev8', 7)
192
192
def test_fill_in_ghost(self):
193
193
graph = self.make_known_graph(test_graph.with_ghost)
194
194
# Add in a couple nodes and then fill in the 'ghost' so that it should
195
195
# cause renumbering of children nodes
196
graph.add_node(b'x', [])
197
graph.add_node(b'y', [b'x'])
198
graph.add_node(b'z', [b'y'])
199
graph.add_node(b'g', [b'z'])
200
self.assertGDFO(graph, b'f', 2)
201
self.assertGDFO(graph, b'e', 3)
202
self.assertGDFO(graph, b'x', 1)
203
self.assertGDFO(graph, b'y', 2)
204
self.assertGDFO(graph, b'z', 3)
205
self.assertGDFO(graph, b'g', 4)
206
self.assertGDFO(graph, b'b', 4)
207
self.assertGDFO(graph, b'd', 5)
208
self.assertGDFO(graph, b'a', 5)
209
self.assertGDFO(graph, b'c', 6)
196
graph.add_node('x', [])
197
graph.add_node('y', ['x'])
198
graph.add_node('z', ['y'])
199
graph.add_node('g', ['z'])
200
self.assertGDFO(graph, 'f', 2)
201
self.assertGDFO(graph, 'e', 3)
202
self.assertGDFO(graph, 'x', 1)
203
self.assertGDFO(graph, 'y', 2)
204
self.assertGDFO(graph, 'z', 3)
205
self.assertGDFO(graph, 'g', 4)
206
self.assertGDFO(graph, 'b', 4)
207
self.assertGDFO(graph, 'd', 5)
208
self.assertGDFO(graph, 'a', 5)
209
self.assertGDFO(graph, 'c', 6)
212
212
class TestKnownGraphHeads(TestCaseWithKnownGraph):
214
214
scenarios = caching_scenarios() + non_caching_scenarios()
215
do_cache = None # Set by load_tests
215
do_cache = None # Set by load_tests
217
217
def test_heads_null(self):
218
218
graph = self.make_known_graph(test_graph.ancestry_1)
219
self.assertEqual({b'null:'}, graph.heads([b'null:']))
220
self.assertEqual({b'rev1'}, graph.heads([b'null:', b'rev1']))
221
self.assertEqual({b'rev1'}, graph.heads([b'rev1', b'null:']))
222
self.assertEqual({b'rev1'}, graph.heads({b'rev1', b'null:'}))
223
self.assertEqual({b'rev1'}, graph.heads((b'rev1', b'null:')))
219
self.assertEqual({'null:'}, graph.heads(['null:']))
220
self.assertEqual({'rev1'}, graph.heads(['null:', 'rev1']))
221
self.assertEqual({'rev1'}, graph.heads(['rev1', 'null:']))
222
self.assertEqual({'rev1'}, graph.heads({'rev1', 'null:'}))
223
self.assertEqual({'rev1'}, graph.heads(('rev1', 'null:')))
225
225
def test_heads_one(self):
226
226
# A single node will always be a head
227
227
graph = self.make_known_graph(test_graph.ancestry_1)
228
self.assertEqual({b'null:'}, graph.heads([b'null:']))
229
self.assertEqual({b'rev1'}, graph.heads([b'rev1']))
230
self.assertEqual({b'rev2a'}, graph.heads([b'rev2a']))
231
self.assertEqual({b'rev2b'}, graph.heads([b'rev2b']))
232
self.assertEqual({b'rev3'}, graph.heads([b'rev3']))
233
self.assertEqual({b'rev4'}, graph.heads([b'rev4']))
228
self.assertEqual({'null:'}, graph.heads(['null:']))
229
self.assertEqual({'rev1'}, graph.heads(['rev1']))
230
self.assertEqual({'rev2a'}, graph.heads(['rev2a']))
231
self.assertEqual({'rev2b'}, graph.heads(['rev2b']))
232
self.assertEqual({'rev3'}, graph.heads(['rev3']))
233
self.assertEqual({'rev4'}, graph.heads(['rev4']))
235
235
def test_heads_single(self):
236
236
graph = self.make_known_graph(test_graph.ancestry_1)
237
self.assertEqual({b'rev4'}, graph.heads([b'null:', b'rev4']))
238
self.assertEqual({b'rev2a'}, graph.heads([b'rev1', b'rev2a']))
239
self.assertEqual({b'rev2b'}, graph.heads([b'rev1', b'rev2b']))
240
self.assertEqual({b'rev3'}, graph.heads([b'rev1', b'rev3']))
241
self.assertEqual({b'rev3'}, graph.heads([b'rev3', b'rev2a']))
242
self.assertEqual({b'rev4'}, graph.heads([b'rev1', b'rev4']))
243
self.assertEqual({b'rev4'}, graph.heads([b'rev2a', b'rev4']))
244
self.assertEqual({b'rev4'}, graph.heads([b'rev2b', b'rev4']))
245
self.assertEqual({b'rev4'}, graph.heads([b'rev3', b'rev4']))
237
self.assertEqual({'rev4'}, graph.heads(['null:', 'rev4']))
238
self.assertEqual({'rev2a'}, graph.heads(['rev1', 'rev2a']))
239
self.assertEqual({'rev2b'}, graph.heads(['rev1', 'rev2b']))
240
self.assertEqual({'rev3'}, graph.heads(['rev1', 'rev3']))
241
self.assertEqual({'rev3'}, graph.heads(['rev3', 'rev2a']))
242
self.assertEqual({'rev4'}, graph.heads(['rev1', 'rev4']))
243
self.assertEqual({'rev4'}, graph.heads(['rev2a', 'rev4']))
244
self.assertEqual({'rev4'}, graph.heads(['rev2b', 'rev4']))
245
self.assertEqual({'rev4'}, graph.heads(['rev3', 'rev4']))
247
247
def test_heads_two_heads(self):
248
248
graph = self.make_known_graph(test_graph.ancestry_1)
249
self.assertEqual({b'rev2a', b'rev2b'},
250
graph.heads([b'rev2a', b'rev2b']))
251
self.assertEqual({b'rev3', b'rev2b'},
252
graph.heads([b'rev3', b'rev2b']))
249
self.assertEqual({'rev2a', 'rev2b'},
250
graph.heads(['rev2a', 'rev2b']))
251
self.assertEqual({'rev3', 'rev2b'},
252
graph.heads(['rev3', 'rev2b']))
254
254
def test_heads_criss_cross(self):
255
255
graph = self.make_known_graph(test_graph.criss_cross)
256
self.assertEqual({b'rev2a'},
257
graph.heads([b'rev2a', b'rev1']))
258
self.assertEqual({b'rev2b'},
259
graph.heads([b'rev2b', b'rev1']))
260
self.assertEqual({b'rev3a'},
261
graph.heads([b'rev3a', b'rev1']))
262
self.assertEqual({b'rev3b'},
263
graph.heads([b'rev3b', b'rev1']))
264
self.assertEqual({b'rev2a', b'rev2b'},
265
graph.heads([b'rev2a', b'rev2b']))
266
self.assertEqual({b'rev3a'},
267
graph.heads([b'rev3a', b'rev2a']))
268
self.assertEqual({b'rev3a'},
269
graph.heads([b'rev3a', b'rev2b']))
270
self.assertEqual({b'rev3a'},
271
graph.heads([b'rev3a', b'rev2a', b'rev2b']))
272
self.assertEqual({b'rev3b'},
273
graph.heads([b'rev3b', b'rev2a']))
274
self.assertEqual({b'rev3b'},
275
graph.heads([b'rev3b', b'rev2b']))
276
self.assertEqual({b'rev3b'},
277
graph.heads([b'rev3b', b'rev2a', b'rev2b']))
278
self.assertEqual({b'rev3a', b'rev3b'},
279
graph.heads([b'rev3a', b'rev3b']))
280
self.assertEqual({b'rev3a', b'rev3b'},
281
graph.heads([b'rev3a', b'rev3b', b'rev2a', b'rev2b']))
256
self.assertEqual({'rev2a'},
257
graph.heads(['rev2a', 'rev1']))
258
self.assertEqual({'rev2b'},
259
graph.heads(['rev2b', 'rev1']))
260
self.assertEqual({'rev3a'},
261
graph.heads(['rev3a', 'rev1']))
262
self.assertEqual({'rev3b'},
263
graph.heads(['rev3b', 'rev1']))
264
self.assertEqual({'rev2a', 'rev2b'},
265
graph.heads(['rev2a', 'rev2b']))
266
self.assertEqual({'rev3a'},
267
graph.heads(['rev3a', 'rev2a']))
268
self.assertEqual({'rev3a'},
269
graph.heads(['rev3a', 'rev2b']))
270
self.assertEqual({'rev3a'},
271
graph.heads(['rev3a', 'rev2a', 'rev2b']))
272
self.assertEqual({'rev3b'},
273
graph.heads(['rev3b', 'rev2a']))
274
self.assertEqual({'rev3b'},
275
graph.heads(['rev3b', 'rev2b']))
276
self.assertEqual({'rev3b'},
277
graph.heads(['rev3b', 'rev2a', 'rev2b']))
278
self.assertEqual({'rev3a', 'rev3b'},
279
graph.heads(['rev3a', 'rev3b']))
280
self.assertEqual({'rev3a', 'rev3b'},
281
graph.heads(['rev3a', 'rev3b', 'rev2a', 'rev2b']))
283
283
def test_heads_shortcut(self):
284
284
graph = self.make_known_graph(test_graph.history_shortcut)
285
self.assertEqual({b'rev2a', b'rev2b', b'rev2c'},
286
graph.heads([b'rev2a', b'rev2b', b'rev2c']))
287
self.assertEqual({b'rev3a', b'rev3b'},
288
graph.heads([b'rev3a', b'rev3b']))
289
self.assertEqual({b'rev3a', b'rev3b'},
290
graph.heads([b'rev2a', b'rev3a', b'rev3b']))
291
self.assertEqual({b'rev2a', b'rev3b'},
292
graph.heads([b'rev2a', b'rev3b']))
293
self.assertEqual({b'rev2c', b'rev3a'},
294
graph.heads([b'rev2c', b'rev3a']))
285
self.assertEqual({'rev2a', 'rev2b', 'rev2c'},
286
graph.heads(['rev2a', 'rev2b', 'rev2c']))
287
self.assertEqual({'rev3a', 'rev3b'},
288
graph.heads(['rev3a', 'rev3b']))
289
self.assertEqual({'rev3a', 'rev3b'},
290
graph.heads(['rev2a', 'rev3a', 'rev3b']))
291
self.assertEqual({'rev2a', 'rev3b'},
292
graph.heads(['rev2a', 'rev3b']))
293
self.assertEqual({'rev2c', 'rev3a'},
294
graph.heads(['rev2c', 'rev3a']))
296
296
def test_heads_linear(self):
297
297
graph = self.make_known_graph(test_graph.racing_shortcuts)
298
self.assertEqual({b'w'}, graph.heads([b'w', b's']))
299
self.assertEqual({b'z'}, graph.heads([b'w', b's', b'z']))
300
self.assertEqual({b'w', b'q'}, graph.heads([b'w', b's', b'q']))
301
self.assertEqual({b'z'}, graph.heads([b's', b'z']))
298
self.assertEqual({'w'}, graph.heads(['w', 's']))
299
self.assertEqual({'z'}, graph.heads(['w', 's', 'z']))
300
self.assertEqual({'w', 'q'}, graph.heads(['w', 's', 'q']))
301
self.assertEqual({'z'}, graph.heads(['s', 'z']))
303
303
def test_heads_alt_merge(self):
304
304
graph = self.make_known_graph(alt_merge)
305
self.assertEqual({b'c'}, graph.heads([b'a', b'c']))
305
self.assertEqual({'c'}, graph.heads(['a', 'c']))
307
307
def test_heads_with_ghost(self):
308
308
graph = self.make_known_graph(test_graph.with_ghost)
309
self.assertEqual({b'e', b'g'}, graph.heads([b'e', b'g']))
310
self.assertEqual({b'a', b'c'}, graph.heads([b'a', b'c']))
311
self.assertEqual({b'a', b'g'}, graph.heads([b'a', b'g']))
312
self.assertEqual({b'f', b'g'}, graph.heads([b'f', b'g']))
313
self.assertEqual({b'c'}, graph.heads([b'c', b'g']))
314
self.assertEqual({b'c'}, graph.heads([b'c', b'b', b'd', b'g']))
315
self.assertEqual({b'a', b'c'}, graph.heads([b'a', b'c', b'e', b'g']))
316
self.assertEqual({b'a', b'c'}, graph.heads([b'a', b'c', b'f']))
309
self.assertEqual({'e', 'g'}, graph.heads(['e', 'g']))
310
self.assertEqual({'a', 'c'}, graph.heads(['a', 'c']))
311
self.assertEqual({'a', 'g'}, graph.heads(['a', 'g']))
312
self.assertEqual({'f', 'g'}, graph.heads(['f', 'g']))
313
self.assertEqual({'c'}, graph.heads(['c', 'g']))
314
self.assertEqual({'c'}, graph.heads(['c', 'b', 'd', 'g']))
315
self.assertEqual({'a', 'c'}, graph.heads(['a', 'c', 'e', 'g']))
316
self.assertEqual({'a', 'c'}, graph.heads(['a', 'c', 'f']))
318
318
def test_filling_in_ghosts_resets_head_cache(self):
319
319
graph = self.make_known_graph(test_graph.with_ghost)
320
self.assertEqual({b'e', b'g'}, graph.heads([b'e', b'g']))
320
self.assertEqual({'e', 'g'}, graph.heads(['e', 'g']))
321
321
# 'g' is filled in, and decends from 'e', so the heads result is now
323
graph.add_node(b'g', [b'e'])
324
self.assertEqual({b'g'}, graph.heads([b'e', b'g']))
323
graph.add_node('g', ['e'])
324
self.assertEqual({'g'}, graph.heads(['e', 'g']))
327
327
class TestKnownGraphTopoSort(TestCaseWithKnownGraph):