17
17
"""Tests for indices."""
19
from bzrlib import errors
20
from bzrlib.index import *
21
from bzrlib.tests import TestCaseWithMemoryTransport
22
from bzrlib.transport import get_transport
25
class TestGraphIndexBuilder(TestCaseWithMemoryTransport):
24
from ..sixish import int2byte
30
class ErrorTests(tests.TestCase):
32
def test_bad_index_format_signature(self):
33
error = _mod_index.BadIndexFormatSignature("foo", "bar")
34
self.assertEqual("foo is not an index of type bar.",
37
def test_bad_index_data(self):
38
error = _mod_index.BadIndexData("foo")
39
self.assertEqual("Error in data for index foo.",
42
def test_bad_index_duplicate_key(self):
43
error = _mod_index.BadIndexDuplicateKey("foo", "bar")
44
self.assertEqual("The key 'foo' is already in index 'bar'.",
47
def test_bad_index_key(self):
48
error = _mod_index.BadIndexKey("foo")
49
self.assertEqual("The key 'foo' is not a valid key.",
52
def test_bad_index_options(self):
53
error = _mod_index.BadIndexOptions("foo")
54
self.assertEqual("Could not parse options for index foo.",
57
def test_bad_index_value(self):
58
error = _mod_index.BadIndexValue("foo")
59
self.assertEqual("The value 'foo' is not a valid value.",
63
class TestGraphIndexBuilder(tests.TestCaseWithMemoryTransport):
27
65
def test_build_index_empty(self):
28
builder = GraphIndexBuilder()
66
builder = _mod_index.GraphIndexBuilder()
29
67
stream = builder.finish()
30
68
contents = stream.read()
32
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=0\n\n",
70
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=0\n\n",
35
73
def test_build_index_empty_two_element_keys(self):
36
builder = GraphIndexBuilder(key_elements=2)
74
builder = _mod_index.GraphIndexBuilder(key_elements=2)
37
75
stream = builder.finish()
38
76
contents = stream.read()
40
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=0\n\n",
78
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=0\n\n",
43
81
def test_build_index_one_reference_list_empty(self):
44
builder = GraphIndexBuilder(reference_lists=1)
82
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
45
83
stream = builder.finish()
46
84
contents = stream.read()
48
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=0\n\n",
86
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=0\n\n",
51
89
def test_build_index_two_reference_list_empty(self):
52
builder = GraphIndexBuilder(reference_lists=2)
90
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
53
91
stream = builder.finish()
54
92
contents = stream.read()
56
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=0\n\n",
94
b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=0\n\n",
59
97
def test_build_index_one_node_no_refs(self):
60
builder = GraphIndexBuilder()
61
builder.add_node(('akey', ), 'data')
98
builder = _mod_index.GraphIndexBuilder()
99
builder.add_node((b'akey', ), b'data')
62
100
stream = builder.finish()
63
101
contents = stream.read()
65
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
66
"akey\x00\x00\x00data\n\n", contents)
103
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
104
b"akey\x00\x00\x00data\n\n", contents)
68
106
def test_build_index_one_node_no_refs_accepts_empty_reflist(self):
69
builder = GraphIndexBuilder()
70
builder.add_node(('akey', ), 'data', ())
107
builder = _mod_index.GraphIndexBuilder()
108
builder.add_node((b'akey', ), b'data', ())
71
109
stream = builder.finish()
72
110
contents = stream.read()
74
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
75
"akey\x00\x00\x00data\n\n", contents)
112
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
113
b"akey\x00\x00\x00data\n\n", contents)
77
115
def test_build_index_one_node_2_element_keys(self):
78
116
# multipart keys are separated by \x00 - because they are fixed length,
79
117
# not variable this does not cause any issues, and seems clearer to the
81
builder = GraphIndexBuilder(key_elements=2)
82
builder.add_node(('akey', 'secondpart'), 'data')
119
builder = _mod_index.GraphIndexBuilder(key_elements=2)
120
builder.add_node((b'akey', b'secondpart'), b'data')
83
121
stream = builder.finish()
84
122
contents = stream.read()
86
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=1\n"
87
"akey\x00secondpart\x00\x00\x00data\n\n", contents)
124
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=1\n"
125
b"akey\x00secondpart\x00\x00\x00data\n\n", contents)
89
127
def test_add_node_empty_value(self):
90
builder = GraphIndexBuilder()
91
builder.add_node(('akey', ), '')
128
builder = _mod_index.GraphIndexBuilder()
129
builder.add_node((b'akey', ), b'')
92
130
stream = builder.finish()
93
131
contents = stream.read()
95
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
96
"akey\x00\x00\x00\n\n", contents)
133
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
134
b"akey\x00\x00\x00\n\n", contents)
98
136
def test_build_index_nodes_sorted(self):
99
137
# the highest sorted node comes first.
100
builder = GraphIndexBuilder()
138
builder = _mod_index.GraphIndexBuilder()
101
139
# use three to have a good chance of glitching dictionary hash
102
140
# lookups etc. Insert in randomish order that is not correct
103
141
# and not the reverse of the correct order.
104
builder.add_node(('2002', ), 'data')
105
builder.add_node(('2000', ), 'data')
106
builder.add_node(('2001', ), 'data')
142
builder.add_node((b'2002', ), b'data')
143
builder.add_node((b'2000', ), b'data')
144
builder.add_node((b'2001', ), b'data')
107
145
stream = builder.finish()
108
146
contents = stream.read()
109
147
self.assertEqual(
110
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=3\n"
111
"2000\x00\x00\x00data\n"
112
"2001\x00\x00\x00data\n"
113
"2002\x00\x00\x00data\n"
148
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=3\n"
149
b"2000\x00\x00\x00data\n"
150
b"2001\x00\x00\x00data\n"
151
b"2002\x00\x00\x00data\n"
116
154
def test_build_index_2_element_key_nodes_sorted(self):
117
155
# multiple element keys are sorted first-key, second-key.
118
builder = GraphIndexBuilder(key_elements=2)
156
builder = _mod_index.GraphIndexBuilder(key_elements=2)
119
157
# use three values of each key element, to have a good chance of
120
158
# glitching dictionary hash lookups etc. Insert in randomish order that
121
159
# is not correct and not the reverse of the correct order.
122
builder.add_node(('2002', '2002'), 'data')
123
builder.add_node(('2002', '2000'), 'data')
124
builder.add_node(('2002', '2001'), 'data')
125
builder.add_node(('2000', '2002'), 'data')
126
builder.add_node(('2000', '2000'), 'data')
127
builder.add_node(('2000', '2001'), 'data')
128
builder.add_node(('2001', '2002'), 'data')
129
builder.add_node(('2001', '2000'), 'data')
130
builder.add_node(('2001', '2001'), 'data')
160
builder.add_node((b'2002', b'2002'), b'data')
161
builder.add_node((b'2002', b'2000'), b'data')
162
builder.add_node((b'2002', b'2001'), b'data')
163
builder.add_node((b'2000', b'2002'), b'data')
164
builder.add_node((b'2000', b'2000'), b'data')
165
builder.add_node((b'2000', b'2001'), b'data')
166
builder.add_node((b'2001', b'2002'), b'data')
167
builder.add_node((b'2001', b'2000'), b'data')
168
builder.add_node((b'2001', b'2001'), b'data')
131
169
stream = builder.finish()
132
170
contents = stream.read()
133
171
self.assertEqual(
134
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=9\n"
135
"2000\x002000\x00\x00\x00data\n"
136
"2000\x002001\x00\x00\x00data\n"
137
"2000\x002002\x00\x00\x00data\n"
138
"2001\x002000\x00\x00\x00data\n"
139
"2001\x002001\x00\x00\x00data\n"
140
"2001\x002002\x00\x00\x00data\n"
141
"2002\x002000\x00\x00\x00data\n"
142
"2002\x002001\x00\x00\x00data\n"
143
"2002\x002002\x00\x00\x00data\n"
172
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=9\n"
173
b"2000\x002000\x00\x00\x00data\n"
174
b"2000\x002001\x00\x00\x00data\n"
175
b"2000\x002002\x00\x00\x00data\n"
176
b"2001\x002000\x00\x00\x00data\n"
177
b"2001\x002001\x00\x00\x00data\n"
178
b"2001\x002002\x00\x00\x00data\n"
179
b"2002\x002000\x00\x00\x00data\n"
180
b"2002\x002001\x00\x00\x00data\n"
181
b"2002\x002002\x00\x00\x00data\n"
146
184
def test_build_index_reference_lists_are_included_one(self):
147
builder = GraphIndexBuilder(reference_lists=1)
148
builder.add_node(('key', ), 'data', ([], ))
185
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
186
builder.add_node((b'key', ), b'data', ([], ))
149
187
stream = builder.finish()
150
188
contents = stream.read()
151
189
self.assertEqual(
152
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
153
"key\x00\x00\x00data\n"
190
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
191
b"key\x00\x00\x00data\n"
156
194
def test_build_index_reference_lists_with_2_element_keys(self):
157
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)
158
builder.add_node(('key', 'key2'), 'data', ([], ))
195
builder = _mod_index.GraphIndexBuilder(reference_lists=1, key_elements=2)
196
builder.add_node((b'key', b'key2'), b'data', ([], ))
159
197
stream = builder.finish()
160
198
contents = stream.read()
161
199
self.assertEqual(
162
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\nlen=1\n"
163
"key\x00key2\x00\x00\x00data\n"
200
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\nlen=1\n"
201
b"key\x00key2\x00\x00\x00data\n"
166
204
def test_build_index_reference_lists_are_included_two(self):
167
builder = GraphIndexBuilder(reference_lists=2)
168
builder.add_node(('key', ), 'data', ([], []))
205
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
206
builder.add_node((b'key', ), b'data', ([], []))
169
207
stream = builder.finish()
170
208
contents = stream.read()
171
209
self.assertEqual(
172
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
173
"key\x00\x00\t\x00data\n"
210
b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
211
b"key\x00\x00\t\x00data\n"
176
214
def test_clear_cache(self):
177
builder = GraphIndexBuilder(reference_lists=2)
215
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
178
216
# This is a no-op, but the api should exist
179
217
builder.clear_cache()
181
219
def test_node_references_are_byte_offsets(self):
182
builder = GraphIndexBuilder(reference_lists=1)
183
builder.add_node(('reference', ), 'data', ([], ))
184
builder.add_node(('key', ), 'data', ([('reference', )], ))
220
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
221
builder.add_node((b'reference', ), b'data', ([], ))
222
builder.add_node((b'key', ), b'data', ([(b'reference', )], ))
185
223
stream = builder.finish()
186
224
contents = stream.read()
187
225
self.assertEqual(
188
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=2\n"
189
"key\x00\x0072\x00data\n"
190
"reference\x00\x00\x00data\n"
226
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=2\n"
227
b"key\x00\x0072\x00data\n"
228
b"reference\x00\x00\x00data\n"
193
231
def test_node_references_are_cr_delimited(self):
194
builder = GraphIndexBuilder(reference_lists=1)
195
builder.add_node(('reference', ), 'data', ([], ))
196
builder.add_node(('reference2', ), 'data', ([], ))
197
builder.add_node(('key', ), 'data', ([('reference', ), ('reference2', )], ))
232
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
233
builder.add_node((b'reference', ), b'data', ([], ))
234
builder.add_node((b'reference2', ), b'data', ([], ))
235
builder.add_node((b'key', ), b'data',
236
([(b'reference', ), (b'reference2', )], ))
198
237
stream = builder.finish()
199
238
contents = stream.read()
200
239
self.assertEqual(
201
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=3\n"
202
"key\x00\x00077\r094\x00data\n"
203
"reference\x00\x00\x00data\n"
204
"reference2\x00\x00\x00data\n"
240
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=3\n"
241
b"key\x00\x00077\r094\x00data\n"
242
b"reference\x00\x00\x00data\n"
243
b"reference2\x00\x00\x00data\n"
207
246
def test_multiple_reference_lists_are_tab_delimited(self):
208
builder = GraphIndexBuilder(reference_lists=2)
209
builder.add_node(('keference', ), 'data', ([], []))
210
builder.add_node(('rey', ), 'data', ([('keference', )], [('keference', )]))
247
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
248
builder.add_node((b'keference', ), b'data', ([], []))
249
builder.add_node((b'rey', ), b'data',
250
([(b'keference', )], [(b'keference', )]))
211
251
stream = builder.finish()
212
252
contents = stream.read()
213
253
self.assertEqual(
214
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=2\n"
215
"keference\x00\x00\t\x00data\n"
216
"rey\x00\x0059\t59\x00data\n"
254
b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=2\n"
255
b"keference\x00\x00\t\x00data\n"
256
b"rey\x00\x0059\t59\x00data\n"
219
259
def test_add_node_referencing_missing_key_makes_absent(self):
220
builder = GraphIndexBuilder(reference_lists=1)
221
builder.add_node(('rey', ), 'data', ([('beference', ), ('aeference2', )], ))
260
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
261
builder.add_node((b'rey', ), b'data',
262
([(b'beference', ), (b'aeference2', )], ))
222
263
stream = builder.finish()
223
264
contents = stream.read()
224
265
self.assertEqual(
225
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
226
"aeference2\x00a\x00\x00\n"
227
"beference\x00a\x00\x00\n"
228
"rey\x00\x00074\r059\x00data\n"
266
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
267
b"aeference2\x00a\x00\x00\n"
268
b"beference\x00a\x00\x00\n"
269
b"rey\x00\x00074\r059\x00data\n"
231
272
def test_node_references_three_digits(self):
232
273
# test the node digit expands as needed.
233
builder = GraphIndexBuilder(reference_lists=1)
234
references = [(str(val), ) for val in reversed(range(9))]
235
builder.add_node(('2-key', ), '', (references, ))
274
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
275
references = [((b"%d" % val), ) for val in range(8, -1, -1)]
276
builder.add_node((b'2-key', ), b'', (references, ))
236
277
stream = builder.finish()
237
278
contents = stream.read()
238
279
self.assertEqualDiff(
239
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
243
"2-key\x00\x00151\r145\r139\r133\r127\r121\r071\r065\r059\x00\n"
280
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
284
b"2-key\x00\x00151\r145\r139\r133\r127\r121\r071\r065\r059\x00\n"
252
293
def test_absent_has_no_reference_overhead(self):
253
294
# the offsets after an absent record should be correct when there are
254
295
# >1 reference lists.
255
builder = GraphIndexBuilder(reference_lists=2)
256
builder.add_node(('parent', ), '', ([('aail', ), ('zther', )], []))
296
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
297
builder.add_node((b'parent', ), b'', ([(b'aail', ), (b'zther', )], []))
257
298
stream = builder.finish()
258
299
contents = stream.read()
259
300
self.assertEqual(
260
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
261
"aail\x00a\x00\x00\n"
262
"parent\x00\x0059\r84\t\x00\n"
263
"zther\x00a\x00\x00\n"
301
b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
302
b"aail\x00a\x00\x00\n"
303
b"parent\x00\x0059\r84\t\x00\n"
304
b"zther\x00a\x00\x00\n"
266
307
def test_add_node_bad_key(self):
267
builder = GraphIndexBuilder()
268
for bad_char in '\t\n\x0b\x0c\r\x00 ':
269
self.assertRaises(errors.BadIndexKey, builder.add_node,
270
('a%skey' % bad_char, ), 'data')
271
self.assertRaises(errors.BadIndexKey, builder.add_node,
273
self.assertRaises(errors.BadIndexKey, builder.add_node,
274
'not-a-tuple', 'data')
308
builder = _mod_index.GraphIndexBuilder()
309
for bad_char in bytearray(b'\t\n\x0b\x0c\r\x00 '):
310
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
311
(b'a%skey' % int2byte(bad_char), ), b'data')
312
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
314
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
315
b'not-a-tuple', b'data')
275
316
# not enough length
276
self.assertRaises(errors.BadIndexKey, builder.add_node,
317
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
279
self.assertRaises(errors.BadIndexKey, builder.add_node,
280
('primary', 'secondary'), 'data')
320
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
321
(b'primary', b'secondary'), b'data')
281
322
# secondary key elements get checked too:
282
builder = GraphIndexBuilder(key_elements=2)
283
for bad_char in '\t\n\x0b\x0c\r\x00 ':
284
self.assertRaises(errors.BadIndexKey, builder.add_node,
285
('prefix', 'a%skey' % bad_char), 'data')
323
builder = _mod_index.GraphIndexBuilder(key_elements=2)
324
for bad_char in bytearray(b'\t\n\x0b\x0c\r\x00 '):
325
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
326
(b'prefix', b'a%skey' % int2byte(bad_char)), b'data')
287
328
def test_add_node_bad_data(self):
288
builder = GraphIndexBuilder()
289
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
291
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
329
builder = _mod_index.GraphIndexBuilder()
330
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
332
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
294
335
def test_add_node_bad_mismatched_ref_lists_length(self):
295
builder = GraphIndexBuilder()
296
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
298
builder = GraphIndexBuilder(reference_lists=1)
299
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
301
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
303
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
305
builder = GraphIndexBuilder(reference_lists=2)
306
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
308
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
310
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
311
'data aa', ([], [], []))
336
builder = _mod_index.GraphIndexBuilder()
337
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
339
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
340
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
342
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
344
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
345
b'data aa', ([], []))
346
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
347
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
349
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
351
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
352
b'data aa', ([], [], []))
313
354
def test_add_node_bad_key_in_reference_lists(self):
314
355
# first list, first key - trivial
315
builder = GraphIndexBuilder(reference_lists=1)
316
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
317
'data aa', ([('a key', )], ))
356
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
357
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
358
b'data aa', ([(b'a key', )], ))
318
359
# references keys must be tuples too
319
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
320
'data aa', (['not-a-tuple'], ))
360
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
361
b'data aa', (['not-a-tuple'], ))
321
362
# not enough length
322
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
363
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
364
b'data aa', ([()], ))
325
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
326
'data aa', ([('primary', 'secondary')], ))
366
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
367
b'data aa', ([(b'primary', b'secondary')], ))
327
368
# need to check more than the first key in the list
328
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
329
'data aa', ([('agoodkey', ), ('that is a bad key', )], ))
369
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
370
b'data aa', ([(b'agoodkey', ), (b'that is a bad key', )], ))
330
371
# and if there is more than one list it should be getting checked
332
builder = GraphIndexBuilder(reference_lists=2)
333
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
334
'data aa', ([], ['a bad key']))
373
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
374
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
375
b'data aa', ([], ['a bad key']))
336
377
def test_add_duplicate_key(self):
337
builder = GraphIndexBuilder()
338
builder.add_node(('key', ), 'data')
339
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node, ('key', ),
378
builder = _mod_index.GraphIndexBuilder()
379
builder.add_node((b'key', ), b'data')
380
self.assertRaises(_mod_index.BadIndexDuplicateKey,
381
builder.add_node, (b'key', ), b'data')
342
383
def test_add_duplicate_key_2_elements(self):
343
builder = GraphIndexBuilder(key_elements=2)
344
builder.add_node(('key', 'key'), 'data')
345
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node,
346
('key', 'key'), 'data')
384
builder = _mod_index.GraphIndexBuilder(key_elements=2)
385
builder.add_node((b'key', b'key'), b'data')
386
self.assertRaises(_mod_index.BadIndexDuplicateKey, builder.add_node,
387
(b'key', b'key'), b'data')
348
389
def test_add_key_after_referencing_key(self):
349
builder = GraphIndexBuilder(reference_lists=1)
350
builder.add_node(('key', ), 'data', ([('reference', )], ))
351
builder.add_node(('reference', ), 'data', ([],))
390
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
391
builder.add_node((b'key', ), b'data', ([(b'reference', )], ))
392
builder.add_node((b'reference', ), b'data', ([],))
353
394
def test_add_key_after_referencing_key_2_elements(self):
354
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)
355
builder.add_node(('k', 'ey'), 'data', ([('reference', 'tokey')], ))
356
builder.add_node(('reference', 'tokey'), 'data', ([],))
395
builder = _mod_index.GraphIndexBuilder(reference_lists=1, key_elements=2)
396
builder.add_node((b'k', b'ey'), b'data', ([(b'reference', b'tokey')], ))
397
builder.add_node((b'reference', b'tokey'), b'data', ([],))
358
399
def test_set_optimize(self):
359
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)
400
builder = _mod_index.GraphIndexBuilder(reference_lists=1, key_elements=2)
360
401
builder.set_optimize(for_size=True)
361
402
self.assertTrue(builder._optimize_for_size)
362
403
builder.set_optimize(for_size=False)
363
404
self.assertFalse(builder._optimize_for_size)
366
class TestGraphIndex(TestCaseWithMemoryTransport):
407
class TestGraphIndex(tests.TestCaseWithMemoryTransport):
368
409
def make_key(self, number):
369
return (str(number) + 'X'*100,)
410
return ((b'%d' % number) + b'X'*100,)
371
412
def make_value(self, number):
372
return str(number) + 'Y'*100
413
return (b'%d' % number) + b'Y'*100
374
415
def make_nodes(self, count=64):
375
416
# generate a big enough index that we only read some of it on a typical
782
823
def test_iter_entries_references_resolved(self):
783
824
index = self.make_index(1, nodes=[
784
(('name', ), 'data', ([('ref', ), ('ref', )], )),
785
(('ref', ), 'refdata', ([], ))])
786
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),('ref',)),)),
787
(index, ('ref', ), 'refdata', ((), ))]),
788
set(index.iter_entries([('name',), ('ref',)])))
825
((b'name', ), b'data', ([(b'ref', ), (b'ref', )], )),
826
((b'ref', ), b'refdata', ([], ))])
827
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',), (b'ref',)),)),
828
(index, (b'ref', ), b'refdata', ((), ))},
829
set(index.iter_entries([(b'name',), (b'ref',)])))
790
831
def test_iter_entries_references_2_refs_resolved(self):
791
832
index = self.make_index(2, nodes=[
792
(('name', ), 'data', ([('ref', )], [('ref', )])),
793
(('ref', ), 'refdata', ([], []))])
794
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),), (('ref',),))),
795
(index, ('ref', ), 'refdata', ((), ()))]),
796
set(index.iter_entries([('name',), ('ref',)])))
833
((b'name', ), b'data', ([(b'ref', )], [(b'ref', )])),
834
((b'ref', ), b'refdata', ([], []))])
835
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),), ((b'ref',),))),
836
(index, (b'ref', ), b'refdata', ((), ()))},
837
set(index.iter_entries([(b'name',), (b'ref',)])))
798
839
def test_iteration_absent_skipped(self):
799
840
index = self.make_index(1, nodes=[
800
(('name', ), 'data', ([('ref', )], ))])
801
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
841
((b'name', ), b'data', ([(b'ref', )], ))])
842
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
802
843
set(index.iter_all_entries()))
803
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
804
set(index.iter_entries([('name', )])))
805
self.assertEqual([], list(index.iter_entries([('ref', )])))
844
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
845
set(index.iter_entries([(b'name', )])))
846
self.assertEqual([], list(index.iter_entries([(b'ref', )])))
807
848
def test_iteration_absent_skipped_2_element_keys(self):
808
849
index = self.make_index(1, key_elements=2, nodes=[
809
(('name', 'fin'), 'data', ([('ref', 'erence')], ))])
810
self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
811
set(index.iter_all_entries()))
812
self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
813
set(index.iter_entries([('name', 'fin')])))
814
self.assertEqual([], list(index.iter_entries([('ref', 'erence')])))
850
((b'name', b'fin'), b'data', ([(b'ref', b'erence')], ))])
851
self.assertEqual([(index, (b'name', b'fin'), b'data', (((b'ref', b'erence'),),))],
852
list(index.iter_all_entries()))
853
self.assertEqual([(index, (b'name', b'fin'), b'data', (((b'ref', b'erence'),),))],
854
list(index.iter_entries([(b'name', b'fin')])))
855
self.assertEqual([], list(index.iter_entries([(b'ref', b'erence')])))
816
857
def test_iter_all_keys(self):
817
858
index = self.make_index(1, nodes=[
818
(('name', ), 'data', ([('ref', )], )),
819
(('ref', ), 'refdata', ([], ))])
820
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
821
(index, ('ref', ), 'refdata', ((), ))]),
822
set(index.iter_entries([('name', ), ('ref', )])))
859
((b'name', ), b'data', ([(b'ref', )], )),
860
((b'ref', ), b'refdata', ([], ))])
861
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
862
(index, (b'ref', ), b'refdata', ((), ))},
863
set(index.iter_entries([(b'name', ), (b'ref', )])))
824
865
def test_iter_nothing_empty(self):
825
866
index = self.make_index()
828
869
def test_iter_missing_entry_empty(self):
829
870
index = self.make_index()
830
self.assertEqual([], list(index.iter_entries([('a', )])))
871
self.assertEqual([], list(index.iter_entries([(b'a', )])))
832
873
def test_iter_missing_entry_empty_no_size(self):
833
index = self.make_index()
834
index = GraphIndex(index._transport, 'index', None)
835
self.assertEqual([], list(index.iter_entries([('a', )])))
874
idx = self.make_index()
875
idx = _mod_index.GraphIndex(idx._transport, b'index', None)
876
self.assertEqual([], list(idx.iter_entries([(b'a', )])))
837
878
def test_iter_key_prefix_1_element_key_None(self):
838
879
index = self.make_index()
839
self.assertRaises(errors.BadIndexKey, list,
880
self.assertRaises(_mod_index.BadIndexKey, list,
840
881
index.iter_entries_prefix([(None, )]))
842
883
def test_iter_key_prefix_wrong_length(self):
843
884
index = self.make_index()
844
self.assertRaises(errors.BadIndexKey, list,
845
index.iter_entries_prefix([('foo', None)]))
885
self.assertRaises(_mod_index.BadIndexKey, list,
886
index.iter_entries_prefix([(b'foo', None)]))
846
887
index = self.make_index(key_elements=2)
847
self.assertRaises(errors.BadIndexKey, list,
848
index.iter_entries_prefix([('foo', )]))
849
self.assertRaises(errors.BadIndexKey, list,
850
index.iter_entries_prefix([('foo', None, None)]))
888
self.assertRaises(_mod_index.BadIndexKey, list,
889
index.iter_entries_prefix([(b'foo', )]))
890
self.assertRaises(_mod_index.BadIndexKey, list,
891
index.iter_entries_prefix([(b'foo', None, None)]))
852
893
def test_iter_key_prefix_1_key_element_no_refs(self):
853
894
index = self.make_index( nodes=[
854
(('name', ), 'data', ()),
855
(('ref', ), 'refdata', ())])
856
self.assertEqual(set([(index, ('name', ), 'data'),
857
(index, ('ref', ), 'refdata')]),
858
set(index.iter_entries_prefix([('name', ), ('ref', )])))
895
((b'name', ), b'data', ()),
896
((b'ref', ), b'refdata', ())])
897
self.assertEqual({(index, (b'name', ), b'data'),
898
(index, (b'ref', ), b'refdata')},
899
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
860
901
def test_iter_key_prefix_1_key_element_refs(self):
861
902
index = self.make_index(1, nodes=[
862
(('name', ), 'data', ([('ref', )], )),
863
(('ref', ), 'refdata', ([], ))])
864
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
865
(index, ('ref', ), 'refdata', ((), ))]),
866
set(index.iter_entries_prefix([('name', ), ('ref', )])))
903
((b'name', ), b'data', ([(b'ref', )], )),
904
((b'ref', ), b'refdata', ([], ))])
905
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
906
(index, (b'ref', ), b'refdata', ((), ))},
907
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
868
909
def test_iter_key_prefix_2_key_element_no_refs(self):
869
910
index = self.make_index(key_elements=2, nodes=[
870
(('name', 'fin1'), 'data', ()),
871
(('name', 'fin2'), 'beta', ()),
872
(('ref', 'erence'), 'refdata', ())])
873
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
874
(index, ('ref', 'erence'), 'refdata')]),
875
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
876
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
877
(index, ('name', 'fin2'), 'beta')]),
878
set(index.iter_entries_prefix([('name', None)])))
911
((b'name', b'fin1'), b'data', ()),
912
((b'name', b'fin2'), b'beta', ()),
913
((b'ref', b'erence'), b'refdata', ())])
914
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
915
(index, (b'ref', b'erence'), b'refdata')},
916
set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
917
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
918
(index, (b'name', b'fin2'), b'beta')},
919
set(index.iter_entries_prefix([(b'name', None)])))
880
921
def test_iter_key_prefix_2_key_element_refs(self):
881
922
index = self.make_index(1, key_elements=2, nodes=[
882
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
883
(('name', 'fin2'), 'beta', ([], )),
884
(('ref', 'erence'), 'refdata', ([], ))])
885
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
886
(index, ('ref', 'erence'), 'refdata', ((), ))]),
887
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
888
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
889
(index, ('name', 'fin2'), 'beta', ((), ))]),
890
set(index.iter_entries_prefix([('name', None)])))
923
((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], )),
924
((b'name', b'fin2'), b'beta', ([], )),
925
((b'ref', b'erence'), b'refdata', ([], ))])
926
self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
927
(index, (b'ref', b'erence'), b'refdata', ((), ))},
928
set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
929
self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
930
(index, (b'name', b'fin2'), b'beta', ((), ))},
931
set(index.iter_entries_prefix([(b'name', None)])))
892
933
def test_key_count_empty(self):
893
934
index = self.make_index()
894
935
self.assertEqual(0, index.key_count())
896
937
def test_key_count_one(self):
897
index = self.make_index(nodes=[(('name', ), '', ())])
938
index = self.make_index(nodes=[((b'name', ), b'', ())])
898
939
self.assertEqual(1, index.key_count())
900
941
def test_key_count_two(self):
901
942
index = self.make_index(nodes=[
902
(('name', ), '', ()), (('foo', ), '', ())])
943
((b'name', ), b'', ()), ((b'foo', ), b'', ())])
903
944
self.assertEqual(2, index.key_count())
905
946
def test_read_and_parse_tracks_real_read_value(self):
1128
1170
log.append(self._index)
1129
1171
return self._index.clear_cache()
1131
index = CombinedGraphIndex([])
1132
index1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1133
index.insert_index(0, ClearCacheProxy(index1))
1134
index2 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1135
index.insert_index(1, ClearCacheProxy(index2))
1173
idx = _mod_index.CombinedGraphIndex([])
1174
idx1 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
1175
idx.insert_index(0, ClearCacheProxy(idx1))
1176
idx2 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
1177
idx.insert_index(1, ClearCacheProxy(idx2))
1136
1178
# CombinedGraphIndex should call 'clear_cache()' on all children
1138
self.assertEqual(sorted([index1, index2]), sorted(log))
1180
self.assertEqual(sorted([idx1, idx2]), sorted(log))
1140
1182
def test_iter_all_entries_empty(self):
1141
index = CombinedGraphIndex([])
1142
self.assertEqual([], list(index.iter_all_entries()))
1183
idx = _mod_index.CombinedGraphIndex([])
1184
self.assertEqual([], list(idx.iter_all_entries()))
1144
1186
def test_iter_all_entries_children_empty(self):
1145
index1 = self.make_index('name')
1146
index = CombinedGraphIndex([index1])
1147
self.assertEqual([], list(index.iter_all_entries()))
1187
idx1 = self.make_index('name')
1188
idx = _mod_index.CombinedGraphIndex([idx1])
1189
self.assertEqual([], list(idx.iter_all_entries()))
1149
1191
def test_iter_all_entries_simple(self):
1150
index1 = self.make_index('name', nodes=[(('name', ), 'data', ())])
1151
index = CombinedGraphIndex([index1])
1152
self.assertEqual([(index1, ('name', ), 'data')],
1153
list(index.iter_all_entries()))
1192
idx1 = self.make_index('name', nodes=[((b'name', ), b'data', ())])
1193
idx = _mod_index.CombinedGraphIndex([idx1])
1194
self.assertEqual([(idx1, (b'name', ), b'data')],
1195
list(idx.iter_all_entries()))
1155
1197
def test_iter_all_entries_two_indices(self):
1156
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1157
index2 = self.make_index('name2', nodes=[(('2', ), '', ())])
1158
index = CombinedGraphIndex([index1, index2])
1159
self.assertEqual([(index1, ('name', ), 'data'),
1160
(index2, ('2', ), '')],
1161
list(index.iter_all_entries()))
1198
idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
1199
idx2 = self.make_index('name2', nodes=[((b'2', ), b'', ())])
1200
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1201
self.assertEqual([(idx1, (b'name', ), b'data'),
1202
(idx2, (b'2', ), b'')],
1203
list(idx.iter_all_entries()))
1163
1205
def test_iter_entries_two_indices_dup_key(self):
1164
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1165
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
1166
index = CombinedGraphIndex([index1, index2])
1167
self.assertEqual([(index1, ('name', ), 'data')],
1168
list(index.iter_entries([('name', )])))
1206
idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
1207
idx2 = self.make_index('name2', nodes=[((b'name', ), b'data', ())])
1208
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1209
self.assertEqual([(idx1, (b'name', ), b'data')],
1210
list(idx.iter_entries([(b'name', )])))
1170
1212
def test_iter_all_entries_two_indices_dup_key(self):
1171
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1172
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
1173
index = CombinedGraphIndex([index1, index2])
1174
self.assertEqual([(index1, ('name', ), 'data')],
1175
list(index.iter_all_entries()))
1213
idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
1214
idx2 = self.make_index('name2', nodes=[((b'name', ), b'data', ())])
1215
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1216
self.assertEqual([(idx1, (b'name', ), b'data')],
1217
list(idx.iter_all_entries()))
1177
1219
def test_iter_key_prefix_2_key_element_refs(self):
1178
index1 = self.make_index('1', 1, key_elements=2, nodes=[
1179
(('name', 'fin1'), 'data', ([('ref', 'erence')], ))])
1180
index2 = self.make_index('2', 1, key_elements=2, nodes=[
1181
(('name', 'fin2'), 'beta', ([], )),
1182
(('ref', 'erence'), 'refdata', ([], ))])
1183
index = CombinedGraphIndex([index1, index2])
1184
self.assertEqual(set([(index1, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1185
(index2, ('ref', 'erence'), 'refdata', ((), ))]),
1186
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1187
self.assertEqual(set([(index1, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1188
(index2, ('name', 'fin2'), 'beta', ((), ))]),
1189
set(index.iter_entries_prefix([('name', None)])))
1220
idx1 = self.make_index('1', 1, key_elements=2, nodes=[
1221
((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], ))])
1222
idx2 = self.make_index(b'2', 1, key_elements=2, nodes=[
1223
((b'name', b'fin2'), b'beta', ([], )),
1224
((b'ref', b'erence'), b'refdata', ([], ))])
1225
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1226
self.assertEqual({(idx1, (b'name', b'fin1'), b'data',
1227
(((b'ref', b'erence'),),)),
1228
(idx2, (b'ref', b'erence'), b'refdata', ((), ))},
1229
set(idx.iter_entries_prefix([(b'name', b'fin1'),
1230
(b'ref', b'erence')])))
1231
self.assertEqual({(idx1, (b'name', b'fin1'), b'data',
1232
(((b'ref', b'erence'),),)),
1233
(idx2, (b'name', b'fin2'), b'beta', ((), ))},
1234
set(idx.iter_entries_prefix([(b'name', None)])))
1191
1236
def test_iter_nothing_empty(self):
1192
index = CombinedGraphIndex([])
1193
self.assertEqual([], list(index.iter_entries([])))
1237
idx = _mod_index.CombinedGraphIndex([])
1238
self.assertEqual([], list(idx.iter_entries([])))
1195
1240
def test_iter_nothing_children_empty(self):
1196
index1 = self.make_index('name')
1197
index = CombinedGraphIndex([index1])
1198
self.assertEqual([], list(index.iter_entries([])))
1241
idx1 = self.make_index('name')
1242
idx = _mod_index.CombinedGraphIndex([idx1])
1243
self.assertEqual([], list(idx.iter_entries([])))
1200
1245
def test_iter_all_keys(self):
1201
index1 = self.make_index('1', 1, nodes=[
1202
(('name', ), 'data', ([('ref', )], ))])
1203
index2 = self.make_index('2', 1, nodes=[
1204
(('ref', ), 'refdata', ((), ))])
1205
index = CombinedGraphIndex([index1, index2])
1206
self.assertEqual(set([(index1, ('name', ), 'data', ((('ref', ), ), )),
1207
(index2, ('ref', ), 'refdata', ((), ))]),
1208
set(index.iter_entries([('name', ), ('ref', )])))
1246
idx1 = self.make_index('1', 1, nodes=[((b'name', ), b'data',
1248
idx2 = self.make_index('2', 1, nodes=[((b'ref', ), b'refdata', ((), ))])
1249
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1250
self.assertEqual({(idx1, (b'name', ), b'data', (((b'ref', ), ), )),
1251
(idx2, (b'ref', ), b'refdata', ((), ))},
1252
set(idx.iter_entries([(b'name', ), (b'ref', )])))
1210
1254
def test_iter_all_keys_dup_entry(self):
1211
index1 = self.make_index('1', 1, nodes=[
1212
(('name', ), 'data', ([('ref', )], )),
1213
(('ref', ), 'refdata', ([], ))])
1214
index2 = self.make_index('2', 1, nodes=[
1215
(('ref', ), 'refdata', ([], ))])
1216
index = CombinedGraphIndex([index1, index2])
1217
self.assertEqual(set([(index1, ('name', ), 'data', ((('ref',),),)),
1218
(index1, ('ref', ), 'refdata', ((), ))]),
1219
set(index.iter_entries([('name', ), ('ref', )])))
1255
idx1 = self.make_index('1', 1, nodes=[((b'name', ), b'data',
1257
((b'ref', ), b'refdata', ([], ))])
1258
idx2 = self.make_index('2', 1, nodes=[((b'ref', ), b'refdata', ([], ))])
1259
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1260
self.assertEqual({(idx1, (b'name', ), b'data', (((b'ref',),),)),
1261
(idx1, (b'ref', ), b'refdata', ((), ))},
1262
set(idx.iter_entries([(b'name', ), (b'ref', )])))
1221
1264
def test_iter_missing_entry_empty(self):
1222
index = CombinedGraphIndex([])
1223
self.assertEqual([], list(index.iter_entries([('a', )])))
1265
idx = _mod_index.CombinedGraphIndex([])
1266
self.assertEqual([], list(idx.iter_entries([('a', )])))
1225
1268
def test_iter_missing_entry_one_index(self):
1226
index1 = self.make_index('1')
1227
index = CombinedGraphIndex([index1])
1228
self.assertEqual([], list(index.iter_entries([('a', )])))
1269
idx1 = self.make_index('1')
1270
idx = _mod_index.CombinedGraphIndex([idx1])
1271
self.assertEqual([], list(idx.iter_entries([(b'a', )])))
1230
1273
def test_iter_missing_entry_two_index(self):
1231
index1 = self.make_index('1')
1232
index2 = self.make_index('2')
1233
index = CombinedGraphIndex([index1, index2])
1234
self.assertEqual([], list(index.iter_entries([('a', )])))
1274
idx1 = self.make_index('1')
1275
idx2 = self.make_index('2')
1276
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1277
self.assertEqual([], list(idx.iter_entries([('a', )])))
1236
1279
def test_iter_entry_present_one_index_only(self):
1237
index1 = self.make_index('1', nodes=[(('key', ), '', ())])
1238
index2 = self.make_index('2', nodes=[])
1239
index = CombinedGraphIndex([index1, index2])
1240
self.assertEqual([(index1, ('key', ), '')],
1241
list(index.iter_entries([('key', )])))
1280
idx1 = self.make_index('1', nodes=[((b'key', ), b'', ())])
1281
idx2 = self.make_index('2', nodes=[])
1282
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1283
self.assertEqual([(idx1, (b'key', ), b'')],
1284
list(idx.iter_entries([(b'key', )])))
1242
1285
# and in the other direction
1243
index = CombinedGraphIndex([index2, index1])
1244
self.assertEqual([(index1, ('key', ), '')],
1245
list(index.iter_entries([('key', )])))
1286
idx = _mod_index.CombinedGraphIndex([idx2, idx1])
1287
self.assertEqual([(idx1, (b'key', ), b'')],
1288
list(idx.iter_entries([(b'key', )])))
1247
1290
def test_key_count_empty(self):
1248
index1 = self.make_index('1', nodes=[])
1249
index2 = self.make_index('2', nodes=[])
1250
index = CombinedGraphIndex([index1, index2])
1251
self.assertEqual(0, index.key_count())
1291
idx1 = self.make_index('1', nodes=[])
1292
idx2 = self.make_index('2', nodes=[])
1293
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1294
self.assertEqual(0, idx.key_count())
1253
1296
def test_key_count_sums_index_keys(self):
1254
index1 = self.make_index('1', nodes=[
1257
index2 = self.make_index('2', nodes=[(('1',), '', ())])
1258
index = CombinedGraphIndex([index1, index2])
1259
self.assertEqual(3, index.key_count())
1297
idx1 = self.make_index('1', nodes=[
1299
((b'2',), b'', ())])
1300
idx2 = self.make_index('2', nodes=[((b'1',), b'', ())])
1301
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1302
self.assertEqual(3, idx.key_count())
1261
1304
def test_validate_bad_child_index_errors(self):
1262
1305
trans = self.get_transport()
1263
trans.put_bytes('name', "not an index\n")
1264
index1 = GraphIndex(trans, 'name', 13)
1265
index = CombinedGraphIndex([index1])
1266
self.assertRaises(errors.BadIndexFormatSignature, index.validate)
1306
trans.put_bytes('name', b"not an index\n")
1307
idx1 = _mod_index.GraphIndex(trans, 'name', 13)
1308
idx = _mod_index.CombinedGraphIndex([idx1])
1309
self.assertRaises(_mod_index.BadIndexFormatSignature, idx.validate)
1268
1311
def test_validate_empty(self):
1269
index = CombinedGraphIndex([])
1312
idx = _mod_index.CombinedGraphIndex([])
1272
1315
def test_key_count_reloads(self):
1273
index, reload_counter = self.make_combined_index_with_missing()
1274
self.assertEqual(2, index.key_count())
1316
idx, reload_counter = self.make_combined_index_with_missing()
1317
self.assertEqual(2, idx.key_count())
1275
1318
self.assertEqual([1, 1, 0], reload_counter)
1277
1320
def test_key_count_no_reload(self):
1278
index, reload_counter = self.make_combined_index_with_missing()
1279
index._reload_func = None
1321
idx, reload_counter = self.make_combined_index_with_missing()
1322
idx._reload_func = None
1280
1323
# Without a _reload_func we just raise the exception
1281
self.assertRaises(errors.NoSuchFile, index.key_count)
1324
self.assertRaises(errors.NoSuchFile, idx.key_count)
1283
1326
def test_key_count_reloads_and_fails(self):
1284
1327
# We have deleted all underlying indexes, so we will try to reload, but
1285
1328
# still fail. This is mostly to test we don't get stuck in an infinite
1286
1329
# loop trying to reload
1287
index, reload_counter = self.make_combined_index_with_missing(
1289
self.assertRaises(errors.NoSuchFile, index.key_count)
1330
idx, reload_counter = self.make_combined_index_with_missing(
1332
self.assertRaises(errors.NoSuchFile, idx.key_count)
1290
1333
self.assertEqual([2, 1, 1], reload_counter)
1292
1335
def test_iter_entries_reloads(self):
1293
1336
index, reload_counter = self.make_combined_index_with_missing()
1294
result = list(index.iter_entries([('1',), ('2',), ('3',)]))
1337
result = list(index.iter_entries([(b'1',), (b'2',), (b'3',)]))
1295
1338
index3 = index._indices[0]
1296
self.assertEqual([(index3, ('1',), ''), (index3, ('2',), '')],
1339
self.assertEqual([(index3, (b'1',), b''), (index3, (b'2',), b'')],
1298
1341
self.assertEqual([1, 1, 0], reload_counter)
1468
1511
self.assertEqual(set(), missing_keys)
1470
1513
def test_find_ancestors_missing_keys(self):
1475
1518
index1 = self.make_index('12', ref_lists=1, nodes=[
1476
(key1, 'value', ([],)),
1477
(key2, 'value', ([key1],)),
1519
(key1, b'value', ([],)),
1520
(key2, b'value', ([key1],)),
1479
1522
index2 = self.make_index('34', ref_lists=1, nodes=[
1480
(key3, 'value', ([key2],)),
1523
(key3, b'value', ([key2],)),
1482
c_index = CombinedGraphIndex([index1, index2])
1525
c_index = _mod_index.CombinedGraphIndex([index1, index2])
1483
1526
# Searching for a key which is actually not present at all should
1484
1527
# eventually converge
1485
1528
parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1486
1529
self.assertEqual({}, parent_map)
1487
self.assertEqual(set([key4]), missing_keys)
1530
self.assertEqual({key4}, missing_keys)
1489
1532
def test_find_ancestors_no_indexes(self):
1490
c_index = CombinedGraphIndex([])
1533
c_index = _mod_index.CombinedGraphIndex([])
1492
1535
parent_map, missing_keys = c_index.find_ancestry([key1], 0)
1493
1536
self.assertEqual({}, parent_map)
1494
self.assertEqual(set([key1]), missing_keys)
1537
self.assertEqual({key1}, missing_keys)
1496
1539
def test_find_ancestors_ghost_parent(self):
1501
1544
index1 = self.make_index('12', ref_lists=1, nodes=[
1502
(key1, 'value', ([],)),
1503
(key2, 'value', ([key1],)),
1545
(key1, b'value', ([],)),
1546
(key2, b'value', ([key1],)),
1505
1548
index2 = self.make_index('34', ref_lists=1, nodes=[
1506
(key4, 'value', ([key2, key3],)),
1549
(key4, b'value', ([key2, key3],)),
1508
c_index = CombinedGraphIndex([index1, index2])
1551
c_index = _mod_index.CombinedGraphIndex([index1, index2])
1509
1552
# Searching for a key which is actually not present at all should
1510
1553
# eventually converge
1511
1554
parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1512
1555
self.assertEqual({key4: (key2, key3), key2: (key1,), key1: ()},
1514
self.assertEqual(set([key3]), missing_keys)
1557
self.assertEqual({key3}, missing_keys)
1516
1559
def test__find_ancestors_empty_index(self):
1517
index = self.make_index('test', ref_lists=1, key_elements=1, nodes=[])
1560
idx = self.make_index('test', ref_lists=1, key_elements=1, nodes=[])
1518
1561
parent_map = {}
1519
1562
missing_keys = set()
1520
search_keys = index._find_ancestors([('one',), ('two',)], 0, parent_map,
1563
search_keys = idx._find_ancestors([(b'one',), (b'two',)], 0, parent_map,
1522
1565
self.assertEqual(set(), search_keys)
1523
1566
self.assertEqual({}, parent_map)
1524
self.assertEqual(set([('one',), ('two',)]), missing_keys)
1527
class TestInMemoryGraphIndex(TestCaseWithMemoryTransport):
1567
self.assertEqual({(b'one',), (b'two',)}, missing_keys)
1570
class TestInMemoryGraphIndex(tests.TestCaseWithMemoryTransport):
1529
1572
def make_index(self, ref_lists=0, key_elements=1, nodes=[]):
1530
result = InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1573
result = _mod_index.InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1531
1574
result.add_nodes(nodes)
1534
1577
def test_add_nodes_no_refs(self):
1535
1578
index = self.make_index(0)
1536
index.add_nodes([(('name', ), 'data')])
1537
index.add_nodes([(('name2', ), ''), (('name3', ), '')])
1538
self.assertEqual(set([
1539
(index, ('name', ), 'data'),
1540
(index, ('name2', ), ''),
1541
(index, ('name3', ), ''),
1542
]), set(index.iter_all_entries()))
1579
index.add_nodes([((b'name', ), b'data')])
1580
index.add_nodes([((b'name2', ), b''), ((b'name3', ), b'')])
1582
(index, (b'name', ), b'data'),
1583
(index, (b'name2', ), b''),
1584
(index, (b'name3', ), b''),
1585
}, set(index.iter_all_entries()))
1544
1587
def test_add_nodes(self):
1545
1588
index = self.make_index(1)
1546
index.add_nodes([(('name', ), 'data', ([],))])
1547
index.add_nodes([(('name2', ), '', ([],)), (('name3', ), '', ([('r', )],))])
1548
self.assertEqual(set([
1549
(index, ('name', ), 'data', ((),)),
1550
(index, ('name2', ), '', ((),)),
1551
(index, ('name3', ), '', ((('r', ), ), )),
1552
]), set(index.iter_all_entries()))
1589
index.add_nodes([((b'name', ), b'data', ([],))])
1590
index.add_nodes([((b'name2', ), b'', ([],)), ((b'name3', ), b'', ([(b'r', )],))])
1592
(index, (b'name', ), b'data', ((),)),
1593
(index, (b'name2', ), b'', ((),)),
1594
(index, (b'name3', ), b'', (((b'r', ), ), )),
1595
}, set(index.iter_all_entries()))
1554
1597
def test_iter_all_entries_empty(self):
1555
1598
index = self.make_index()
1556
1599
self.assertEqual([], list(index.iter_all_entries()))
1558
1601
def test_iter_all_entries_simple(self):
1559
index = self.make_index(nodes=[(('name', ), 'data')])
1560
self.assertEqual([(index, ('name', ), 'data')],
1602
index = self.make_index(nodes=[((b'name', ), b'data')])
1603
self.assertEqual([(index, (b'name', ), b'data')],
1561
1604
list(index.iter_all_entries()))
1563
1606
def test_iter_all_entries_references(self):
1564
1607
index = self.make_index(1, nodes=[
1565
(('name', ), 'data', ([('ref', )], )),
1566
(('ref', ), 'refdata', ([], ))])
1567
self.assertEqual(set([(index, ('name', ), 'data', ((('ref', ),),)),
1568
(index, ('ref', ), 'refdata', ((), ))]),
1608
((b'name', ), b'data', ([(b'ref', )], )),
1609
((b'ref', ), b'refdata', ([], ))])
1610
self.assertEqual({(index, (b'name', ), b'data', (((b'ref', ),),)),
1611
(index, (b'ref', ), b'refdata', ((), ))},
1569
1612
set(index.iter_all_entries()))
1571
1614
def test_iteration_absent_skipped(self):
1572
1615
index = self.make_index(1, nodes=[
1573
(('name', ), 'data', ([('ref', )], ))])
1574
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
1616
((b'name', ), b'data', ([(b'ref', )], ))])
1617
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
1575
1618
set(index.iter_all_entries()))
1576
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
1577
set(index.iter_entries([('name', )])))
1578
self.assertEqual([], list(index.iter_entries([('ref', )])))
1619
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
1620
set(index.iter_entries([(b'name', )])))
1621
self.assertEqual([], list(index.iter_entries([(b'ref', )])))
1580
1623
def test_iter_all_keys(self):
1581
1624
index = self.make_index(1, nodes=[
1582
(('name', ), 'data', ([('ref', )], )),
1583
(('ref', ), 'refdata', ([], ))])
1584
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
1585
(index, ('ref', ), 'refdata', ((), ))]),
1586
set(index.iter_entries([('name', ), ('ref', )])))
1625
((b'name', ), b'data', ([(b'ref', )], )),
1626
((b'ref', ), b'refdata', ([], ))])
1627
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
1628
(index, (b'ref', ), b'refdata', ((), ))},
1629
set(index.iter_entries([(b'name', ), (b'ref', )])))
1588
1631
def test_iter_key_prefix_1_key_element_no_refs(self):
1589
1632
index = self.make_index( nodes=[
1590
(('name', ), 'data'),
1591
(('ref', ), 'refdata')])
1592
self.assertEqual(set([(index, ('name', ), 'data'),
1593
(index, ('ref', ), 'refdata')]),
1594
set(index.iter_entries_prefix([('name', ), ('ref', )])))
1633
((b'name', ), b'data'),
1634
((b'ref', ), b'refdata')])
1635
self.assertEqual({(index, (b'name', ), b'data'),
1636
(index, (b'ref', ), b'refdata')},
1637
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
1596
1639
def test_iter_key_prefix_1_key_element_refs(self):
1597
1640
index = self.make_index(1, nodes=[
1598
(('name', ), 'data', ([('ref', )], )),
1599
(('ref', ), 'refdata', ([], ))])
1600
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
1601
(index, ('ref', ), 'refdata', ((), ))]),
1602
set(index.iter_entries_prefix([('name', ), ('ref', )])))
1641
((b'name', ), b'data', ([(b'ref', )], )),
1642
((b'ref', ), b'refdata', ([], ))])
1643
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
1644
(index, (b'ref', ), b'refdata', ((), ))},
1645
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
1604
1647
def test_iter_key_prefix_2_key_element_no_refs(self):
1605
1648
index = self.make_index(key_elements=2, nodes=[
1606
(('name', 'fin1'), 'data'),
1607
(('name', 'fin2'), 'beta'),
1608
(('ref', 'erence'), 'refdata')])
1609
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
1610
(index, ('ref', 'erence'), 'refdata')]),
1611
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1612
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
1613
(index, ('name', 'fin2'), 'beta')]),
1614
set(index.iter_entries_prefix([('name', None)])))
1649
((b'name', b'fin1'), b'data'),
1650
((b'name', b'fin2'), b'beta'),
1651
((b'ref', b'erence'), b'refdata')])
1652
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
1653
(index, (b'ref', b'erence'), b'refdata')},
1654
set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
1655
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
1656
(index, (b'name', b'fin2'), b'beta')},
1657
set(index.iter_entries_prefix([(b'name', None)])))
1616
1659
def test_iter_key_prefix_2_key_element_refs(self):
1617
1660
index = self.make_index(1, key_elements=2, nodes=[
1618
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
1619
(('name', 'fin2'), 'beta', ([], )),
1620
(('ref', 'erence'), 'refdata', ([], ))])
1621
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1622
(index, ('ref', 'erence'), 'refdata', ((), ))]),
1623
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1624
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1625
(index, ('name', 'fin2'), 'beta', ((), ))]),
1626
set(index.iter_entries_prefix([('name', None)])))
1661
((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], )),
1662
((b'name', b'fin2'), b'beta', ([], )),
1663
((b'ref', b'erence'), b'refdata', ([], ))])
1664
self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
1665
(index, (b'ref', b'erence'), b'refdata', ((), ))},
1666
set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
1667
self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
1668
(index, (b'name', b'fin2'), b'beta', ((), ))},
1669
set(index.iter_entries_prefix([(b'name', None)])))
1628
1671
def test_iter_nothing_empty(self):
1629
1672
index = self.make_index()
1650
1693
index.validate()
1652
1695
def test_validate_no_refs_content(self):
1653
index = self.make_index(nodes=[(('key', ), 'value')])
1696
index = self.make_index(nodes=[((b'key', ), b'value')])
1654
1697
index.validate()
1657
class TestGraphIndexPrefixAdapter(TestCaseWithMemoryTransport):
1700
class TestGraphIndexPrefixAdapter(tests.TestCaseWithMemoryTransport):
1659
def make_index(self, ref_lists=1, key_elements=2, nodes=[], add_callback=False):
1660
result = InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1702
def make_index(self, ref_lists=1, key_elements=2, nodes=[],
1703
add_callback=False):
1704
result = _mod_index.InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1661
1705
result.add_nodes(nodes)
1662
1706
if add_callback:
1663
1707
add_nodes_callback = result.add_nodes
1665
1709
add_nodes_callback = None
1666
adapter = GraphIndexPrefixAdapter(result, ('prefix', ), key_elements - 1,
1710
adapter = _mod_index.GraphIndexPrefixAdapter(
1711
result, (b'prefix', ), key_elements - 1,
1667
1712
add_nodes_callback=add_nodes_callback)
1668
1713
return result, adapter
1670
1715
def test_add_node(self):
1671
1716
index, adapter = self.make_index(add_callback=True)
1672
adapter.add_node(('key',), 'value', ((('ref',),),))
1673
self.assertEqual(set([(index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))]),
1717
adapter.add_node((b'key',), b'value', (((b'ref',),),))
1718
self.assertEqual({(index, (b'prefix', b'key'), b'value',
1719
(((b'prefix', b'ref'),),))},
1674
1720
set(index.iter_all_entries()))
1676
1722
def test_add_nodes(self):
1677
1723
index, adapter = self.make_index(add_callback=True)
1678
1724
adapter.add_nodes((
1679
(('key',), 'value', ((('ref',),),)),
1680
(('key2',), 'value2', ((),)),
1725
((b'key',), b'value', (((b'ref',),),)),
1726
((b'key2',), b'value2', ((),)),
1682
self.assertEqual(set([
1683
(index, ('prefix', 'key2'), 'value2', ((),)),
1684
(index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))
1729
(index, (b'prefix', b'key2'), b'value2', ((),)),
1730
(index, (b'prefix', b'key'), b'value', (((b'prefix', b'ref'),),))
1686
1732
set(index.iter_all_entries()))
1688
1734
def test_construct(self):
1689
index = InMemoryGraphIndex()
1690
adapter = GraphIndexPrefixAdapter(index, ('prefix', ), 1)
1735
idx = _mod_index.InMemoryGraphIndex()
1736
adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1)
1692
1738
def test_construct_with_callback(self):
1693
index = InMemoryGraphIndex()
1694
adapter = GraphIndexPrefixAdapter(index, ('prefix', ), 1, index.add_nodes)
1739
idx = _mod_index.InMemoryGraphIndex()
1740
adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1,
1696
1743
def test_iter_all_entries_cross_prefix_map_errors(self):
1697
1744
index, adapter = self.make_index(nodes=[
1698
(('prefix', 'key1'), 'data1', ((('prefixaltered', 'key2'),),))])
1699
self.assertRaises(errors.BadIndexData, list, adapter.iter_all_entries())
1745
((b'prefix', b'key1'), b'data1', (((b'prefixaltered', b'key2'),),))])
1746
self.assertRaises(_mod_index.BadIndexData, list, adapter.iter_all_entries())
1701
1748
def test_iter_all_entries(self):
1702
1749
index, adapter = self.make_index(nodes=[
1703
(('notprefix', 'key1'), 'data', ((), )),
1704
(('prefix', 'key1'), 'data1', ((), )),
1705
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1706
self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),
1707
(index, ('key2', ), 'data2', ((('key1',),),))]),
1750
((b'notprefix', b'key1'), b'data', ((), )),
1751
((b'prefix', b'key1'), b'data1', ((), )),
1752
((b'prefix', b'key2'), b'data2', (((b'prefix', b'key1'),),))])
1753
self.assertEqual({(index, (b'key1', ), b'data1', ((),)),
1754
(index, (b'key2', ), b'data2', (((b'key1',),),))},
1708
1755
set(adapter.iter_all_entries()))
1710
1757
def test_iter_entries(self):
1711
1758
index, adapter = self.make_index(nodes=[
1712
(('notprefix', 'key1'), 'data', ((), )),
1713
(('prefix', 'key1'), 'data1', ((), )),
1714
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1759
((b'notprefix', b'key1'), b'data', ((), )),
1760
((b'prefix', b'key1'), b'data1', ((), )),
1761
((b'prefix', b'key2'), b'data2', (((b'prefix', b'key1'),),))])
1715
1762
# ask for many - get all
1716
self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),
1717
(index, ('key2', ), 'data2', ((('key1', ),),))]),
1718
set(adapter.iter_entries([('key1', ), ('key2', )])))
1763
self.assertEqual({(index, (b'key1', ), b'data1', ((),)),
1764
(index, (b'key2', ), b'data2', (((b'key1', ),),))},
1765
set(adapter.iter_entries([(b'key1', ), (b'key2', )])))
1719
1766
# ask for one, get one
1720
self.assertEqual(set([(index, ('key1', ), 'data1', ((),))]),
1721
set(adapter.iter_entries([('key1', )])))
1767
self.assertEqual({(index, (b'key1', ), b'data1', ((),))},
1768
set(adapter.iter_entries([(b'key1', )])))
1722
1769
# ask for missing, get none
1723
1770
self.assertEqual(set(),
1724
set(adapter.iter_entries([('key3', )])))
1771
set(adapter.iter_entries([(b'key3', )])))
1726
1773
def test_iter_entries_prefix(self):
1727
1774
index, adapter = self.make_index(key_elements=3, nodes=[
1728
(('notprefix', 'foo', 'key1'), 'data', ((), )),
1729
(('prefix', 'prefix2', 'key1'), 'data1', ((), )),
1730
(('prefix', 'prefix2', 'key2'), 'data2', ((('prefix', 'prefix2', 'key1'),),))])
1775
((b'notprefix', b'foo', b'key1'), b'data', ((), )),
1776
((b'prefix', b'prefix2', b'key1'), b'data1', ((), )),
1777
((b'prefix', b'prefix2', b'key2'), b'data2', (((b'prefix', b'prefix2', b'key1'),),))])
1731
1778
# ask for a prefix, get the results for just that prefix, adjusted.
1732
self.assertEqual(set([(index, ('prefix2', 'key1', ), 'data1', ((),)),
1733
(index, ('prefix2', 'key2', ), 'data2', ((('prefix2', 'key1', ),),))]),
1734
set(adapter.iter_entries_prefix([('prefix2', None)])))
1779
self.assertEqual({(index, (b'prefix2', b'key1', ), b'data1', ((),)),
1780
(index, (b'prefix2', b'key2', ), b'data2', (((b'prefix2', b'key1', ),),))},
1781
set(adapter.iter_entries_prefix([(b'prefix2', None)])))
1736
1783
def test_key_count_no_matching_keys(self):
1737
1784
index, adapter = self.make_index(nodes=[
1738
(('notprefix', 'key1'), 'data', ((), ))])
1785
((b'notprefix', b'key1'), b'data', ((), ))])
1739
1786
self.assertEqual(0, adapter.key_count())
1741
1788
def test_key_count_some_keys(self):
1742
1789
index, adapter = self.make_index(nodes=[
1743
(('notprefix', 'key1'), 'data', ((), )),
1744
(('prefix', 'key1'), 'data1', ((), )),
1745
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1790
((b'notprefix', b'key1'), b'data', ((), )),
1791
((b'prefix', b'key1'), b'data1', ((), )),
1792
((b'prefix', b'key2'), b'data2', (((b'prefix', b'key1'),),))])
1746
1793
self.assertEqual(2, adapter.key_count())
1748
1795
def test_validate(self):