922
933
index = self.make_index(nodes=[(('key', ), 'value', ())])
936
# XXX: external_references tests are duplicated in test_btree_index. We
937
# probably should have per_graph_index tests...
938
def test_external_references_no_refs(self):
939
index = self.make_index(ref_lists=0, nodes=[])
940
self.assertRaises(ValueError, index.external_references, 0)
942
def test_external_references_no_results(self):
943
index = self.make_index(ref_lists=1, nodes=[
944
(('key',), 'value', ([],))])
945
self.assertEqual(set(), index.external_references(0))
947
def test_external_references_missing_ref(self):
948
missing_key = ('missing',)
949
index = self.make_index(ref_lists=1, nodes=[
950
(('key',), 'value', ([missing_key],))])
951
self.assertEqual(set([missing_key]), index.external_references(0))
953
def test_external_references_multiple_ref_lists(self):
954
missing_key = ('missing',)
955
index = self.make_index(ref_lists=2, nodes=[
956
(('key',), 'value', ([], [missing_key]))])
957
self.assertEqual(set([]), index.external_references(0))
958
self.assertEqual(set([missing_key]), index.external_references(1))
960
def test_external_references_two_records(self):
961
index = self.make_index(ref_lists=1, nodes=[
962
(('key-1',), 'value', ([('key-2',)],)),
963
(('key-2',), 'value', ([],)),
965
self.assertEqual(set([]), index.external_references(0))
967
def test__find_ancestors(self):
970
index = self.make_index(ref_lists=1, key_elements=1, nodes=[
971
(key1, 'value', ([key2],)),
972
(key2, 'value', ([],)),
976
search_keys = index._find_ancestors([key1], 0, parent_map, missing_keys)
977
self.assertEqual({key1: (key2,)}, parent_map)
978
self.assertEqual(set(), missing_keys)
979
self.assertEqual(set([key2]), search_keys)
980
search_keys = index._find_ancestors(search_keys, 0, parent_map,
982
self.assertEqual({key1: (key2,), key2: ()}, parent_map)
983
self.assertEqual(set(), missing_keys)
984
self.assertEqual(set(), search_keys)
986
def test__find_ancestors_w_missing(self):
990
index = self.make_index(ref_lists=1, key_elements=1, nodes=[
991
(key1, 'value', ([key2],)),
992
(key2, 'value', ([],)),
996
search_keys = index._find_ancestors([key2, key3], 0, parent_map,
998
self.assertEqual({key2: ()}, parent_map)
999
self.assertEqual(set([key3]), missing_keys)
1000
self.assertEqual(set(), search_keys)
1002
def test__find_ancestors_dont_search_known(self):
1006
index = self.make_index(ref_lists=1, key_elements=1, nodes=[
1007
(key1, 'value', ([key2],)),
1008
(key2, 'value', ([key3],)),
1009
(key3, 'value', ([],)),
1011
# We already know about key2, so we won't try to search for key3
1012
parent_map = {key2: (key3,)}
1013
missing_keys = set()
1014
search_keys = index._find_ancestors([key1], 0, parent_map,
1016
self.assertEqual({key1: (key2,), key2: (key3,)}, parent_map)
1017
self.assertEqual(set(), missing_keys)
1018
self.assertEqual(set(), search_keys)
1020
def test_supports_unlimited_cache(self):
1021
builder = GraphIndexBuilder(0, key_elements=1)
1022
stream = builder.finish()
1023
trans = get_transport(self.get_url())
1024
size = trans.put_file('index', stream)
1025
# It doesn't matter what unlimited_cache does here, just that it can be
1027
index = GraphIndex(trans, 'index', size, unlimited_cache=True)
926
1030
class TestCombinedGraphIndex(TestCaseWithMemoryTransport):
978
1082
index.insert_index(0, index1)
979
1083
self.assertEqual([(index1, ('key', ), '')], list(index.iter_all_entries()))
1085
def test_clear_cache(self):
1088
class ClearCacheProxy(object):
1090
def __init__(self, index):
1093
def __getattr__(self, name):
1094
return getattr(self._index)
1096
def clear_cache(self):
1097
log.append(self._index)
1098
return self._index.clear_cache()
1100
index = CombinedGraphIndex([])
1101
index1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1102
index.insert_index(0, ClearCacheProxy(index1))
1103
index2 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1104
index.insert_index(1, ClearCacheProxy(index2))
1105
# CombinedGraphIndex should call 'clear_cache()' on all children
1107
self.assertEqual(sorted([index1, index2]), sorted(log))
981
1109
def test_iter_all_entries_empty(self):
982
1110
index = CombinedGraphIndex([])
983
1111
self.assertEqual([], list(index.iter_all_entries()))
1240
1368
['1', '2', '3'])
1241
1369
self.assertRaises(errors.NoSuchFile, index.validate)
1371
def test_find_ancestors_across_indexes(self):
1376
index1 = self.make_index('12', ref_lists=1, nodes=[
1377
(key1, 'value', ([],)),
1378
(key2, 'value', ([key1],)),
1380
index2 = self.make_index('34', ref_lists=1, nodes=[
1381
(key3, 'value', ([key2],)),
1382
(key4, 'value', ([key3],)),
1384
c_index = CombinedGraphIndex([index1, index2])
1385
parent_map, missing_keys = c_index.find_ancestry([key1], 0)
1386
self.assertEqual({key1: ()}, parent_map)
1387
self.assertEqual(set(), missing_keys)
1388
# Now look for a key from index2 which requires us to find the key in
1389
# the second index, and then continue searching for parents in the
1391
parent_map, missing_keys = c_index.find_ancestry([key3], 0)
1392
self.assertEqual({key1: (), key2: (key1,), key3: (key2,)}, parent_map)
1393
self.assertEqual(set(), missing_keys)
1395
def test_find_ancestors_missing_keys(self):
1400
index1 = self.make_index('12', ref_lists=1, nodes=[
1401
(key1, 'value', ([],)),
1402
(key2, 'value', ([key1],)),
1404
index2 = self.make_index('34', ref_lists=1, nodes=[
1405
(key3, 'value', ([key2],)),
1407
c_index = CombinedGraphIndex([index1, index2])
1408
# Searching for a key which is actually not present at all should
1409
# eventually converge
1410
parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1411
self.assertEqual({}, parent_map)
1412
self.assertEqual(set([key4]), missing_keys)
1414
def test_find_ancestors_no_indexes(self):
1415
c_index = CombinedGraphIndex([])
1417
parent_map, missing_keys = c_index.find_ancestry([key1], 0)
1418
self.assertEqual({}, parent_map)
1419
self.assertEqual(set([key1]), missing_keys)
1421
def test_find_ancestors_ghost_parent(self):
1426
index1 = self.make_index('12', ref_lists=1, nodes=[
1427
(key1, 'value', ([],)),
1428
(key2, 'value', ([key1],)),
1430
index2 = self.make_index('34', ref_lists=1, nodes=[
1431
(key4, 'value', ([key2, key3],)),
1433
c_index = CombinedGraphIndex([index1, index2])
1434
# Searching for a key which is actually not present at all should
1435
# eventually converge
1436
parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1437
self.assertEqual({key4: (key2, key3), key2: (key1,), key1: ()},
1439
self.assertEqual(set([key3]), missing_keys)
1441
def test__find_ancestors_empty_index(self):
1442
index = self.make_index('test', ref_lists=1, key_elements=1, nodes=[])
1444
missing_keys = set()
1445
search_keys = index._find_ancestors([('one',), ('two',)], 0, parent_map,
1447
self.assertEqual(set(), search_keys)
1448
self.assertEqual({}, parent_map)
1449
self.assertEqual(set([('one',), ('two',)]), missing_keys)
1244
1452
class TestInMemoryGraphIndex(TestCaseWithMemoryTransport):