/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_index.py

  • Committer: Martin
  • Date: 2018-06-30 22:18:39 UTC
  • mfrom: (7010 work)
  • mto: This revision was merged to the branch mainline in revision 7012.
  • Revision ID: gzlist@googlemail.com-20180630221839-98zi78xwcggestse
Merge trunk to fix conflict

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
    tests,
22
22
    transport,
23
23
    )
 
24
from ..sixish import int2byte
24
25
from ..bzr import (
25
26
    index as _mod_index,
26
27
    )
66
67
        stream = builder.finish()
67
68
        contents = stream.read()
68
69
        self.assertEqual(
69
 
            "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",
70
71
            contents)
71
72
 
72
73
    def test_build_index_empty_two_element_keys(self):
74
75
        stream = builder.finish()
75
76
        contents = stream.read()
76
77
        self.assertEqual(
77
 
            "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",
78
79
            contents)
79
80
 
80
81
    def test_build_index_one_reference_list_empty(self):
82
83
        stream = builder.finish()
83
84
        contents = stream.read()
84
85
        self.assertEqual(
85
 
            "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",
86
87
            contents)
87
88
 
88
89
    def test_build_index_two_reference_list_empty(self):
90
91
        stream = builder.finish()
91
92
        contents = stream.read()
92
93
        self.assertEqual(
93
 
            "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",
94
95
            contents)
95
96
 
96
97
    def test_build_index_one_node_no_refs(self):
97
98
        builder = _mod_index.GraphIndexBuilder()
98
 
        builder.add_node(('akey', ), 'data')
 
99
        builder.add_node((b'akey', ), b'data')
99
100
        stream = builder.finish()
100
101
        contents = stream.read()
101
102
        self.assertEqual(
102
 
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
103
 
            "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)
104
105
 
105
106
    def test_build_index_one_node_no_refs_accepts_empty_reflist(self):
106
107
        builder = _mod_index.GraphIndexBuilder()
107
 
        builder.add_node(('akey', ), 'data', ())
 
108
        builder.add_node((b'akey', ), b'data', ())
108
109
        stream = builder.finish()
109
110
        contents = stream.read()
110
111
        self.assertEqual(
111
 
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
112
 
            "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)
113
114
 
114
115
    def test_build_index_one_node_2_element_keys(self):
115
116
        # multipart keys are separated by \x00 - because they are fixed length,
116
117
        # not variable this does not cause any issues, and seems clearer to the
117
118
        # author.
118
119
        builder = _mod_index.GraphIndexBuilder(key_elements=2)
119
 
        builder.add_node(('akey', 'secondpart'), 'data')
 
120
        builder.add_node((b'akey', b'secondpart'), b'data')
120
121
        stream = builder.finish()
121
122
        contents = stream.read()
122
123
        self.assertEqual(
123
 
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=1\n"
124
 
            "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)
125
126
 
126
127
    def test_add_node_empty_value(self):
127
128
        builder = _mod_index.GraphIndexBuilder()
128
 
        builder.add_node(('akey', ), '')
 
129
        builder.add_node((b'akey', ), b'')
129
130
        stream = builder.finish()
130
131
        contents = stream.read()
131
132
        self.assertEqual(
132
 
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
133
 
            "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)
134
135
 
135
136
    def test_build_index_nodes_sorted(self):
136
137
        # the highest sorted node comes first.
138
139
        # use three to have a good chance of glitching dictionary hash
139
140
        # lookups etc. Insert in randomish order that is not correct
140
141
        # and not the reverse of the correct order.
141
 
        builder.add_node(('2002', ), 'data')
142
 
        builder.add_node(('2000', ), 'data')
143
 
        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')
144
145
        stream = builder.finish()
145
146
        contents = stream.read()
146
147
        self.assertEqual(
147
 
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=3\n"
148
 
            "2000\x00\x00\x00data\n"
149
 
            "2001\x00\x00\x00data\n"
150
 
            "2002\x00\x00\x00data\n"
151
 
            "\n", contents)
 
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"
 
152
            b"\n", contents)
152
153
 
153
154
    def test_build_index_2_element_key_nodes_sorted(self):
154
155
        # multiple element keys are sorted first-key, second-key.
156
157
        # use three values of each key element, to have a good chance of
157
158
        # glitching dictionary hash lookups etc. Insert in randomish order that
158
159
        # is not correct and not the reverse of the correct order.
159
 
        builder.add_node(('2002', '2002'), 'data')
160
 
        builder.add_node(('2002', '2000'), 'data')
161
 
        builder.add_node(('2002', '2001'), 'data')
162
 
        builder.add_node(('2000', '2002'), 'data')
163
 
        builder.add_node(('2000', '2000'), 'data')
164
 
        builder.add_node(('2000', '2001'), 'data')
165
 
        builder.add_node(('2001', '2002'), 'data')
166
 
        builder.add_node(('2001', '2000'), 'data')
167
 
        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')
168
169
        stream = builder.finish()
169
170
        contents = stream.read()
170
171
        self.assertEqual(
171
 
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=9\n"
172
 
            "2000\x002000\x00\x00\x00data\n"
173
 
            "2000\x002001\x00\x00\x00data\n"
174
 
            "2000\x002002\x00\x00\x00data\n"
175
 
            "2001\x002000\x00\x00\x00data\n"
176
 
            "2001\x002001\x00\x00\x00data\n"
177
 
            "2001\x002002\x00\x00\x00data\n"
178
 
            "2002\x002000\x00\x00\x00data\n"
179
 
            "2002\x002001\x00\x00\x00data\n"
180
 
            "2002\x002002\x00\x00\x00data\n"
181
 
            "\n", contents)
 
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"
 
182
            b"\n", contents)
182
183
 
183
184
    def test_build_index_reference_lists_are_included_one(self):
184
185
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
185
 
        builder.add_node(('key', ), 'data', ([], ))
 
186
        builder.add_node((b'key', ), b'data', ([], ))
186
187
        stream = builder.finish()
187
188
        contents = stream.read()
188
189
        self.assertEqual(
189
 
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
190
 
            "key\x00\x00\x00data\n"
191
 
            "\n", contents)
 
190
            b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
 
191
            b"key\x00\x00\x00data\n"
 
192
            b"\n", contents)
192
193
 
193
194
    def test_build_index_reference_lists_with_2_element_keys(self):
194
195
        builder = _mod_index.GraphIndexBuilder(reference_lists=1, key_elements=2)
195
 
        builder.add_node(('key', 'key2'), 'data', ([], ))
 
196
        builder.add_node((b'key', b'key2'), b'data', ([], ))
196
197
        stream = builder.finish()
197
198
        contents = stream.read()
198
199
        self.assertEqual(
199
 
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\nlen=1\n"
200
 
            "key\x00key2\x00\x00\x00data\n"
201
 
            "\n", contents)
 
200
            b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\nlen=1\n"
 
201
            b"key\x00key2\x00\x00\x00data\n"
 
202
            b"\n", contents)
202
203
 
203
204
    def test_build_index_reference_lists_are_included_two(self):
204
205
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
205
 
        builder.add_node(('key', ), 'data', ([], []))
 
206
        builder.add_node((b'key', ), b'data', ([], []))
206
207
        stream = builder.finish()
207
208
        contents = stream.read()
208
209
        self.assertEqual(
209
 
            "Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
210
 
            "key\x00\x00\t\x00data\n"
211
 
            "\n", contents)
 
210
            b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
 
211
            b"key\x00\x00\t\x00data\n"
 
212
            b"\n", contents)
212
213
 
213
214
    def test_clear_cache(self):
214
215
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
217
218
 
218
219
    def test_node_references_are_byte_offsets(self):
219
220
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
220
 
        builder.add_node(('reference', ), 'data', ([], ))
221
 
        builder.add_node(('key', ), 'data', ([('reference', )], ))
 
221
        builder.add_node((b'reference', ), b'data', ([], ))
 
222
        builder.add_node((b'key', ), b'data', ([(b'reference', )], ))
222
223
        stream = builder.finish()
223
224
        contents = stream.read()
224
225
        self.assertEqual(
225
 
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=2\n"
226
 
            "key\x00\x0072\x00data\n"
227
 
            "reference\x00\x00\x00data\n"
228
 
            "\n", contents)
 
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"
 
229
            b"\n", contents)
229
230
 
230
231
    def test_node_references_are_cr_delimited(self):
231
232
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
232
 
        builder.add_node(('reference', ), 'data', ([], ))
233
 
        builder.add_node(('reference2', ), 'data', ([], ))
234
 
        builder.add_node(('key', ), 'data',
235
 
                         ([('reference', ), ('reference2', )], ))
 
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', )], ))
236
237
        stream = builder.finish()
237
238
        contents = stream.read()
238
239
        self.assertEqual(
239
 
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=3\n"
240
 
            "key\x00\x00077\r094\x00data\n"
241
 
            "reference\x00\x00\x00data\n"
242
 
            "reference2\x00\x00\x00data\n"
243
 
            "\n", contents)
 
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"
 
244
            b"\n", contents)
244
245
 
245
246
    def test_multiple_reference_lists_are_tab_delimited(self):
246
247
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
247
 
        builder.add_node(('keference', ), 'data', ([], []))
248
 
        builder.add_node(('rey', ), 'data',
249
 
                         ([('keference', )], [('keference', )]))
 
248
        builder.add_node((b'keference', ), b'data', ([], []))
 
249
        builder.add_node((b'rey', ), b'data',
 
250
                         ([(b'keference', )], [(b'keference', )]))
250
251
        stream = builder.finish()
251
252
        contents = stream.read()
252
253
        self.assertEqual(
253
 
            "Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=2\n"
254
 
            "keference\x00\x00\t\x00data\n"
255
 
            "rey\x00\x0059\t59\x00data\n"
256
 
            "\n", contents)
 
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"
 
257
            b"\n", contents)
257
258
 
258
259
    def test_add_node_referencing_missing_key_makes_absent(self):
259
260
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
260
 
        builder.add_node(('rey', ), 'data',
261
 
                         ([('beference', ), ('aeference2', )], ))
 
261
        builder.add_node((b'rey', ), b'data',
 
262
                         ([(b'beference', ), (b'aeference2', )], ))
262
263
        stream = builder.finish()
263
264
        contents = stream.read()
264
265
        self.assertEqual(
265
 
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
266
 
            "aeference2\x00a\x00\x00\n"
267
 
            "beference\x00a\x00\x00\n"
268
 
            "rey\x00\x00074\r059\x00data\n"
269
 
            "\n", contents)
 
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"
 
270
            b"\n", contents)
270
271
 
271
272
    def test_node_references_three_digits(self):
272
273
        # test the node digit expands as needed.
273
274
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
274
 
        references = [(str(val), ) for val in range(8, -1, -1)]
275
 
        builder.add_node(('2-key', ), '', (references, ))
 
275
        references = [((b"%d" % val), ) for val in range(8, -1, -1)]
 
276
        builder.add_node((b'2-key', ), b'', (references, ))
276
277
        stream = builder.finish()
277
278
        contents = stream.read()
278
279
        self.assertEqualDiff(
279
 
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
280
 
            "0\x00a\x00\x00\n"
281
 
            "1\x00a\x00\x00\n"
282
 
            "2\x00a\x00\x00\n"
283
 
            "2-key\x00\x00151\r145\r139\r133\r127\r121\r071\r065\r059\x00\n"
284
 
            "3\x00a\x00\x00\n"
285
 
            "4\x00a\x00\x00\n"
286
 
            "5\x00a\x00\x00\n"
287
 
            "6\x00a\x00\x00\n"
288
 
            "7\x00a\x00\x00\n"
289
 
            "8\x00a\x00\x00\n"
290
 
            "\n", contents)
 
280
            b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
 
281
            b"0\x00a\x00\x00\n"
 
282
            b"1\x00a\x00\x00\n"
 
283
            b"2\x00a\x00\x00\n"
 
284
            b"2-key\x00\x00151\r145\r139\r133\r127\r121\r071\r065\r059\x00\n"
 
285
            b"3\x00a\x00\x00\n"
 
286
            b"4\x00a\x00\x00\n"
 
287
            b"5\x00a\x00\x00\n"
 
288
            b"6\x00a\x00\x00\n"
 
289
            b"7\x00a\x00\x00\n"
 
290
            b"8\x00a\x00\x00\n"
 
291
            b"\n", contents)
291
292
 
292
293
    def test_absent_has_no_reference_overhead(self):
293
294
        # the offsets after an absent record should be correct when there are
294
295
        # >1 reference lists.
295
296
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
296
 
        builder.add_node(('parent', ), '', ([('aail', ), ('zther', )], []))
 
297
        builder.add_node((b'parent', ), b'', ([(b'aail', ), (b'zther', )], []))
297
298
        stream = builder.finish()
298
299
        contents = stream.read()
299
300
        self.assertEqual(
300
 
            "Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
301
 
            "aail\x00a\x00\x00\n"
302
 
            "parent\x00\x0059\r84\t\x00\n"
303
 
            "zther\x00a\x00\x00\n"
304
 
            "\n", contents)
 
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"
 
305
            b"\n", contents)
305
306
 
306
307
    def test_add_node_bad_key(self):
307
308
        builder = _mod_index.GraphIndexBuilder()
308
 
        for bad_char in '\t\n\x0b\x0c\r\x00 ':
 
309
        for bad_char in bytearray(b'\t\n\x0b\x0c\r\x00 '):
309
310
            self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
310
 
                ('a%skey' % bad_char, ), 'data')
311
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
312
 
                ('', ), 'data')
313
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
314
 
                'not-a-tuple', 'data')
 
311
                (b'a%skey' % int2byte(bad_char), ), b'data')
 
312
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
 
313
                (b'', ), b'data')
 
314
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
 
315
                b'not-a-tuple', b'data')
315
316
        # not enough length
316
317
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
317
 
                (), 'data')
 
318
                (), b'data')
318
319
        # too long
319
320
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
320
 
                ('primary', 'secondary'), 'data')
 
321
                (b'primary', b'secondary'), b'data')
321
322
        # secondary key elements get checked too:
322
323
        builder = _mod_index.GraphIndexBuilder(key_elements=2)
323
 
        for bad_char in '\t\n\x0b\x0c\r\x00 ':
 
324
        for bad_char in bytearray(b'\t\n\x0b\x0c\r\x00 '):
324
325
            self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
325
 
                ('prefix', 'a%skey' % bad_char), 'data')
 
326
                (b'prefix', b'a%skey' % int2byte(bad_char)), b'data')
326
327
 
327
328
    def test_add_node_bad_data(self):
328
329
        builder = _mod_index.GraphIndexBuilder()
329
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, ('akey', ),
330
 
            'data\naa')
331
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, ('akey', ),
332
 
            'data\x00aa')
 
330
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
 
331
            b'data\naa')
 
332
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
 
333
            b'data\x00aa')
333
334
 
334
335
    def test_add_node_bad_mismatched_ref_lists_length(self):
335
336
        builder = _mod_index.GraphIndexBuilder()
336
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, ('akey', ),
337
 
            'data aa', ([], ))
 
337
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
 
338
            b'data aa', ([], ))
338
339
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
339
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, ('akey', ),
340
 
            'data aa')
341
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, ('akey', ),
342
 
            'data aa', (), )
343
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, ('akey', ),
344
 
            'data aa', ([], []))
 
340
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
 
341
            b'data aa')
 
342
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
 
343
            b'data aa', (), )
 
344
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
 
345
            b'data aa', ([], []))
345
346
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
346
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, ('akey', ),
347
 
            'data aa')
348
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, ('akey', ),
349
 
            'data aa', ([], ))
350
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, ('akey', ),
351
 
            'data aa', ([], [], []))
 
347
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
 
348
            b'data aa')
 
349
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
 
350
            b'data aa', ([], ))
 
351
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
 
352
            b'data aa', ([], [], []))
352
353
 
353
354
    def test_add_node_bad_key_in_reference_lists(self):
354
355
        # first list, first key - trivial
355
356
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
356
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, ('akey', ),
357
 
            'data aa', ([('a key', )], ))
 
357
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
 
358
            b'data aa', ([(b'a key', )], ))
358
359
        # references keys must be tuples too
359
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, ('akey', ),
360
 
            'data aa', (['not-a-tuple'], ))
 
360
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
 
361
            b'data aa', (['not-a-tuple'], ))
361
362
        # not enough length
362
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, ('akey', ),
363
 
            'data aa', ([()], ))
 
363
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
 
364
            b'data aa', ([()], ))
364
365
        # too long
365
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, ('akey', ),
366
 
            'data aa', ([('primary', 'secondary')], ))
 
366
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
 
367
            b'data aa', ([(b'primary', b'secondary')], ))
367
368
        # need to check more than the first key in the list
368
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, ('akey', ),
369
 
            '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', )], ))
370
371
        # and if there is more than one list it should be getting checked
371
372
        # too
372
373
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
373
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, ('akey', ),
374
 
            'data aa', ([], ['a bad key']))
 
374
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
 
375
            b'data aa', ([], ['a bad key']))
375
376
 
376
377
    def test_add_duplicate_key(self):
377
378
        builder = _mod_index.GraphIndexBuilder()
378
 
        builder.add_node(('key', ), 'data')
 
379
        builder.add_node((b'key', ), b'data')
379
380
        self.assertRaises(_mod_index.BadIndexDuplicateKey,
380
 
                          builder.add_node, ('key', ), 'data')
 
381
                          builder.add_node, (b'key', ), b'data')
381
382
 
382
383
    def test_add_duplicate_key_2_elements(self):
383
384
        builder = _mod_index.GraphIndexBuilder(key_elements=2)
384
 
        builder.add_node(('key', 'key'), 'data')
 
385
        builder.add_node((b'key', b'key'), b'data')
385
386
        self.assertRaises(_mod_index.BadIndexDuplicateKey, builder.add_node,
386
 
            ('key', 'key'), 'data')
 
387
            (b'key', b'key'), b'data')
387
388
 
388
389
    def test_add_key_after_referencing_key(self):
389
390
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
390
 
        builder.add_node(('key', ), 'data', ([('reference', )], ))
391
 
        builder.add_node(('reference', ), 'data', ([],))
 
391
        builder.add_node((b'key', ), b'data', ([(b'reference', )], ))
 
392
        builder.add_node((b'reference', ), b'data', ([],))
392
393
 
393
394
    def test_add_key_after_referencing_key_2_elements(self):
394
395
        builder = _mod_index.GraphIndexBuilder(reference_lists=1, key_elements=2)
395
 
        builder.add_node(('k', 'ey'), 'data', ([('reference', 'tokey')], ))
396
 
        builder.add_node(('reference', 'tokey'), 'data', ([],))
 
396
        builder.add_node((b'k', b'ey'), b'data', ([(b'reference', b'tokey')], ))
 
397
        builder.add_node((b'reference', b'tokey'), b'data', ([],))
397
398
 
398
399
    def test_set_optimize(self):
399
400
        builder = _mod_index.GraphIndexBuilder(reference_lists=1, key_elements=2)
406
407
class TestGraphIndex(tests.TestCaseWithMemoryTransport):
407
408
 
408
409
    def make_key(self, number):
409
 
        return (str(number) + 'X'*100,)
 
410
        return ((b'%d' % number) + b'X'*100,)
410
411
 
411
412
    def make_value(self, number):
412
 
            return str(number) + 'Y'*100
 
413
        return (b'%d' % number) + b'Y'*100
413
414
 
414
415
    def make_nodes(self, count=64):
415
416
        # generate a big enough index that we only read some of it on a typical
436
437
        content = builder.finish().read()
437
438
        size = len(content)
438
439
        trans = self.get_transport()
439
 
        trans.put_bytes('index', (' '*offset) + content)
 
440
        trans.put_bytes('index', (b' '*offset) + content)
440
441
        return _mod_index.GraphIndex(trans, 'index', size, offset=offset)
441
442
 
442
443
    def test_clear_cache(self):
447
448
 
448
449
    def test_open_bad_index_no_error(self):
449
450
        trans = self.get_transport()
450
 
        trans.put_bytes('name', "not an index\n")
 
451
        trans.put_bytes('name', b"not an index\n")
451
452
        idx = _mod_index.GraphIndex(trans, 'name', 13)
452
453
 
453
454
    def test_with_offset(self):
496
497
        # do a _lookup_keys_via_location call for the middle of the file, which
497
498
        # is what bisection uses.
498
499
        result = index._lookup_keys_via_location(
499
 
            [(index._size // 2, ('missing', ))])
 
500
            [(index._size // 2, (b'missing', ))])
500
501
        # this should have asked for a readv request, with adjust_for_latency,
501
502
        # and two regions: the header, and half-way into the file.
502
503
        self.assertEqual([
505
506
            index._transport._activity)
506
507
        # and the result should be that the key cannot be present, because this
507
508
        # is a trivial index.
508
 
        self.assertEqual([((index._size // 2, ('missing', )), False)],
 
509
        self.assertEqual([((index._size // 2, (b'missing', )), False)],
509
510
            result)
510
511
        # And this should have caused the file to be fully buffered
511
512
        self.assertIsNot(None, index._nodes)
526
527
        # is what bisection uses.
527
528
        start_lookup = index._size // 2
528
529
        result = index._lookup_keys_via_location(
529
 
            [(start_lookup, ('40missing', ))])
 
530
            [(start_lookup, (b'40missing', ))])
530
531
        # this should have asked for a readv request, with adjust_for_latency,
531
532
        # and two regions: the header, and half-way into the file.
532
533
        self.assertEqual([
536
537
            index._transport._activity)
537
538
        # and the result should be that the key cannot be present, because this
538
539
        # is a trivial index.
539
 
        self.assertEqual([((start_lookup, ('40missing', )), False)],
 
540
        self.assertEqual([((start_lookup, (b'40missing', )), False)],
540
541
            result)
541
542
        # And this should not have caused the file to be fully buffered
542
543
        self.assertIs(None, index._nodes)
550
551
    def test_parsing_non_adjacent_data_trims(self):
551
552
        index = self.make_index(nodes=self.make_nodes(64))
552
553
        result = index._lookup_keys_via_location(
553
 
            [(index._size // 2, ('40', ))])
 
554
            [(index._size // 2, (b'40', ))])
554
555
        # and the result should be that the key cannot be present, because key is
555
556
        # in the middle of the observed data from a 4K read - the smallest transport
556
557
        # will do today with this api.
557
 
        self.assertEqual([((index._size // 2, ('40', )), False)],
 
558
        self.assertEqual([((index._size // 2, (b'40', )), False)],
558
559
            result)
559
560
        # and we should have a parse map that includes the header and the
560
561
        # region that was parsed after trimming.
579
580
        # locations of both keys.
580
581
        index = self.make_index(nodes=self.make_nodes(128))
581
582
        result = index._lookup_keys_via_location(
582
 
            [(index._size // 2, ('40', ))])
 
583
            [(index._size // 2, (b'40', ))])
583
584
        # and we should have a parse map that includes the header and the
584
585
        # region that was parsed after trimming.
585
586
        self.assertEqual([(0, 4045), (11759, 15707)], index._parsed_byte_map)
604
605
        index = self.make_index(nodes=self.make_nodes(64))
605
606
        # lookup the keys in the middle of the file
606
607
        result =index._lookup_keys_via_location(
607
 
            [(index._size // 2, ('40', ))])
 
608
            [(index._size // 2, (b'40', ))])
608
609
        # check the parse map, this determines the test validity
609
610
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
610
611
        self.assertEqual([(None, self.make_key(26)),
617
618
        # be in the index) - even when the byte location we ask for is outside
618
619
        # the parsed region
619
620
        result = index._lookup_keys_via_location(
620
 
            [(4000, ('40', ))])
621
 
        self.assertEqual([((4000, ('40', )), False)],
 
621
            [(4000, (b'40', ))])
 
622
        self.assertEqual([((4000, (b'40', )), False)],
622
623
            result)
623
624
        self.assertEqual([], index._transport._activity)
624
625
 
628
629
        index = self.make_index(nodes=self.make_nodes(64))
629
630
        # lookup the keys in the middle of the file
630
631
        result =index._lookup_keys_via_location(
631
 
            [(index._size // 2, ('40', ))])
 
632
            [(index._size // 2, (b'40', ))])
632
633
        # check the parse map, this determines the test validity
633
634
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
634
635
        self.assertEqual([(None, self.make_key(26)),
655
656
        # ask for the key in the middle, but a key that is located in the
656
657
        # unparsed region before the middle.
657
658
        result =index._lookup_keys_via_location(
658
 
            [(index._size // 2, ('30', ))])
 
659
            [(index._size // 2, (b'30', ))])
659
660
        # check the parse map, this determines the test validity
660
661
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
661
662
        self.assertEqual([(None, self.make_key(26)),
671
672
        # ask for the key in the middle, but a key that is located in the
672
673
        # unparsed region after the middle.
673
674
        result =index._lookup_keys_via_location(
674
 
            [(index._size // 2, ('50', ))])
 
675
            [(index._size // 2, (b'50', ))])
675
676
        # check the parse map, this determines the test validity
676
677
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
677
678
        self.assertEqual([(None, self.make_key(26)),
678
679
                          (self.make_key(31), self.make_key(48))],
679
680
            index._parsed_key_map)
680
 
        self.assertEqual([((index._size // 2, ('50', )), +1)],
 
681
        self.assertEqual([((index._size // 2, (b'50', )), +1)],
681
682
            result)
682
683
 
683
684
    def test_lookup_key_resolves_references(self):
693
694
        index_size = index._size
694
695
        index_center = index_size // 2
695
696
        result = index._lookup_keys_via_location(
696
 
            [(index_center, ('40', ))])
 
697
            [(index_center, (b'40', ))])
697
698
        # check the parse map - only the start and middle should have been
698
699
        # parsed.
699
700
        self.assertEqual([(0, 4027), (10198, 14028)], index._parsed_byte_map)
728
729
        # check that the referred-to-keys are not accessed automatically.
729
730
        index_size = index._size
730
731
        index_center = index_size // 2
731
 
        result = index._lookup_keys_via_location([(index_center, ('40', ))])
 
732
        result = index._lookup_keys_via_location([(index_center, (b'40', ))])
732
733
        # check the parse map - only the start and middle should have been
733
734
        # parsed.
734
735
        self.assertEqual([(0, 3890), (6444, 10274)], index._parsed_byte_map)
759
760
        self.assertEqual([], list(index.iter_all_entries()))
760
761
 
761
762
    def test_iter_all_entries_simple(self):
762
 
        index = self.make_index(nodes=[(('name', ), 'data', ())])
763
 
        self.assertEqual([(index, ('name', ), 'data')],
 
763
        index = self.make_index(nodes=[((b'name', ), b'data', ())])
 
764
        self.assertEqual([(index, (b'name', ), b'data')],
764
765
            list(index.iter_all_entries()))
765
766
 
766
767
    def test_iter_all_entries_simple_2_elements(self):
767
768
        index = self.make_index(key_elements=2,
768
 
            nodes=[(('name', 'surname'), 'data', ())])
769
 
        self.assertEqual([(index, ('name', 'surname'), 'data')],
 
769
            nodes=[((b'name', b'surname'), b'data', ())])
 
770
        self.assertEqual([(index, (b'name', b'surname'), b'data')],
770
771
            list(index.iter_all_entries()))
771
772
 
772
773
    def test_iter_all_entries_references_resolved(self):
773
774
        index = self.make_index(1, nodes=[
774
 
            (('name', ), 'data', ([('ref', )], )),
775
 
            (('ref', ), 'refdata', ([], ))])
776
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
777
 
            (index, ('ref', ), 'refdata', ((), ))},
 
775
            ((b'name', ), b'data', ([(b'ref', )], )),
 
776
            ((b'ref', ), b'refdata', ([], ))])
 
777
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
 
778
            (index, (b'ref', ), b'refdata', ((), ))},
778
779
            set(index.iter_all_entries()))
779
780
 
780
781
    def test_iter_entries_buffers_once(self):
821
822
 
822
823
    def test_iter_entries_references_resolved(self):
823
824
        index = self.make_index(1, nodes=[
824
 
            (('name', ), 'data', ([('ref', ), ('ref', )], )),
825
 
            (('ref', ), 'refdata', ([], ))])
826
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',), ('ref',)),)),
827
 
            (index, ('ref', ), 'refdata', ((), ))},
828
 
            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',)])))
829
830
 
830
831
    def test_iter_entries_references_2_refs_resolved(self):
831
832
        index = self.make_index(2, nodes=[
832
 
            (('name', ), 'data', ([('ref', )], [('ref', )])),
833
 
            (('ref', ), 'refdata', ([], []))])
834
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),), (('ref',),))),
835
 
            (index, ('ref', ), 'refdata', ((), ()))},
836
 
            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',)])))
837
838
 
838
839
    def test_iteration_absent_skipped(self):
839
840
        index = self.make_index(1, nodes=[
840
 
            (('name', ), 'data', ([('ref', )], ))])
841
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),))},
 
841
            ((b'name', ), b'data', ([(b'ref', )], ))])
 
842
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
842
843
            set(index.iter_all_entries()))
843
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),))},
844
 
            set(index.iter_entries([('name', )])))
845
 
        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', )])))
846
847
 
847
848
    def test_iteration_absent_skipped_2_element_keys(self):
848
849
        index = self.make_index(1, key_elements=2, nodes=[
849
 
            (('name', 'fin'), 'data', ([('ref', 'erence')], ))])
850
 
        self.assertEqual({(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))},
851
 
            set(index.iter_all_entries()))
852
 
        self.assertEqual({(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))},
853
 
            set(index.iter_entries([('name', 'fin')])))
854
 
        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')])))
855
856
 
856
857
    def test_iter_all_keys(self):
857
858
        index = self.make_index(1, nodes=[
858
 
            (('name', ), 'data', ([('ref', )], )),
859
 
            (('ref', ), 'refdata', ([], ))])
860
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
861
 
            (index, ('ref', ), 'refdata', ((), ))},
862
 
            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', )])))
863
864
 
864
865
    def test_iter_nothing_empty(self):
865
866
        index = self.make_index()
867
868
 
868
869
    def test_iter_missing_entry_empty(self):
869
870
        index = self.make_index()
870
 
        self.assertEqual([], list(index.iter_entries([('a', )])))
 
871
        self.assertEqual([], list(index.iter_entries([(b'a', )])))
871
872
 
872
873
    def test_iter_missing_entry_empty_no_size(self):
873
874
        idx = self.make_index()
874
 
        idx = _mod_index.GraphIndex(idx._transport, 'index', None)
875
 
        self.assertEqual([], list(idx.iter_entries([('a', )])))
 
875
        idx = _mod_index.GraphIndex(idx._transport, b'index', None)
 
876
        self.assertEqual([], list(idx.iter_entries([(b'a', )])))
876
877
 
877
878
    def test_iter_key_prefix_1_element_key_None(self):
878
879
        index = self.make_index()
882
883
    def test_iter_key_prefix_wrong_length(self):
883
884
        index = self.make_index()
884
885
        self.assertRaises(_mod_index.BadIndexKey, list,
885
 
            index.iter_entries_prefix([('foo', None)]))
 
886
            index.iter_entries_prefix([(b'foo', None)]))
886
887
        index = self.make_index(key_elements=2)
887
888
        self.assertRaises(_mod_index.BadIndexKey, list,
888
 
            index.iter_entries_prefix([('foo', )]))
 
889
            index.iter_entries_prefix([(b'foo', )]))
889
890
        self.assertRaises(_mod_index.BadIndexKey, list,
890
 
            index.iter_entries_prefix([('foo', None, None)]))
 
891
            index.iter_entries_prefix([(b'foo', None, None)]))
891
892
 
892
893
    def test_iter_key_prefix_1_key_element_no_refs(self):
893
894
        index = self.make_index( nodes=[
894
 
            (('name', ), 'data', ()),
895
 
            (('ref', ), 'refdata', ())])
896
 
        self.assertEqual({(index, ('name', ), 'data'),
897
 
            (index, ('ref', ), 'refdata')},
898
 
            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', )])))
899
900
 
900
901
    def test_iter_key_prefix_1_key_element_refs(self):
901
902
        index = self.make_index(1, nodes=[
902
 
            (('name', ), 'data', ([('ref', )], )),
903
 
            (('ref', ), 'refdata', ([], ))])
904
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
905
 
            (index, ('ref', ), 'refdata', ((), ))},
906
 
            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', )])))
907
908
 
908
909
    def test_iter_key_prefix_2_key_element_no_refs(self):
909
910
        index = self.make_index(key_elements=2, nodes=[
910
 
            (('name', 'fin1'), 'data', ()),
911
 
            (('name', 'fin2'), 'beta', ()),
912
 
            (('ref', 'erence'), 'refdata', ())])
913
 
        self.assertEqual({(index, ('name', 'fin1'), 'data'),
914
 
            (index, ('ref', 'erence'), 'refdata')},
915
 
            set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
916
 
        self.assertEqual({(index, ('name', 'fin1'), 'data'),
917
 
            (index, ('name', 'fin2'), 'beta')},
918
 
            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)])))
919
920
 
920
921
    def test_iter_key_prefix_2_key_element_refs(self):
921
922
        index = self.make_index(1, key_elements=2, nodes=[
922
 
            (('name', 'fin1'), 'data', ([('ref', 'erence')], )),
923
 
            (('name', 'fin2'), 'beta', ([], )),
924
 
            (('ref', 'erence'), 'refdata', ([], ))])
925
 
        self.assertEqual({(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
926
 
            (index, ('ref', 'erence'), 'refdata', ((), ))},
927
 
            set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
928
 
        self.assertEqual({(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
929
 
            (index, ('name', 'fin2'), 'beta', ((), ))},
930
 
            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)])))
931
932
 
932
933
    def test_key_count_empty(self):
933
934
        index = self.make_index()
934
935
        self.assertEqual(0, index.key_count())
935
936
 
936
937
    def test_key_count_one(self):
937
 
        index = self.make_index(nodes=[(('name', ), '', ())])
 
938
        index = self.make_index(nodes=[((b'name', ), b'', ())])
938
939
        self.assertEqual(1, index.key_count())
939
940
 
940
941
    def test_key_count_two(self):
941
942
        index = self.make_index(nodes=[
942
 
            (('name', ), '', ()), (('foo', ), '', ())])
 
943
            ((b'name', ), b'', ()), ((b'foo', ), b'', ())])
943
944
        self.assertEqual(2, index.key_count())
944
945
 
945
946
    def test_read_and_parse_tracks_real_read_value(self):
957
958
 
958
959
    def test_read_and_parse_triggers_buffer_all(self):
959
960
        index = self.make_index(key_elements=2, nodes=[
960
 
            (('name', 'fin1'), 'data', ()),
961
 
            (('name', 'fin2'), 'beta', ()),
962
 
            (('ref', 'erence'), 'refdata', ())])
 
961
            ((b'name', b'fin1'), b'data', ()),
 
962
            ((b'name', b'fin2'), b'beta', ()),
 
963
            ((b'ref', b'erence'), b'refdata', ())])
963
964
        self.assertTrue(index._size > 0)
964
965
        self.assertIs(None, index._nodes)
965
966
        index._read_and_parse([(0, index._size)])
967
968
 
968
969
    def test_validate_bad_index_errors(self):
969
970
        trans = self.get_transport()
970
 
        trans.put_bytes('name', "not an index\n")
 
971
        trans.put_bytes('name', b"not an index\n")
971
972
        idx = _mod_index.GraphIndex(trans, 'name', 13)
972
973
        self.assertRaises(_mod_index.BadIndexFormatSignature, idx.validate)
973
974
 
976
977
        trans = self.get_transport()
977
978
        content = trans.get_bytes('index')
978
979
        # change the options line to end with a rather than a parseable number
979
 
        new_content = content[:-2] + 'a\n\n'
 
980
        new_content = content[:-2] + b'a\n\n'
980
981
        trans.put_bytes('index', new_content)
981
982
        self.assertRaises(_mod_index.BadIndexOptions, idx.validate)
982
983
 
989
990
        self.assertRaises(_mod_index.BadIndexData, index.validate)
990
991
 
991
992
    def test_validate_missing_end_line_nonempty(self):
992
 
        index = self.make_index(2, nodes=[(('key', ), '', ([], []))])
 
993
        index = self.make_index(2, nodes=[((b'key', ), b'', ([], []))])
993
994
        trans = self.get_transport()
994
995
        content = trans.get_bytes('index')
995
996
        # truncate the last byte
1001
1002
        index.validate()
1002
1003
 
1003
1004
    def test_validate_no_refs_content(self):
1004
 
        index = self.make_index(nodes=[(('key', ), 'value', ())])
 
1005
        index = self.make_index(nodes=[((b'key', ), b'value', ())])
1005
1006
        index.validate()
1006
1007
 
1007
1008
    # XXX: external_references tests are duplicated in test_btree_index.  We
1012
1013
 
1013
1014
    def test_external_references_no_results(self):
1014
1015
        index = self.make_index(ref_lists=1, nodes=[
1015
 
            (('key',), 'value', ([],))])
 
1016
            ((b'key',), b'value', ([],))])
1016
1017
        self.assertEqual(set(), index.external_references(0))
1017
1018
 
1018
1019
    def test_external_references_missing_ref(self):
1019
 
        missing_key = ('missing',)
 
1020
        missing_key = (b'missing',)
1020
1021
        index = self.make_index(ref_lists=1, nodes=[
1021
 
            (('key',), 'value', ([missing_key],))])
 
1022
            ((b'key',), b'value', ([missing_key],))])
1022
1023
        self.assertEqual({missing_key}, index.external_references(0))
1023
1024
 
1024
1025
    def test_external_references_multiple_ref_lists(self):
1025
 
        missing_key = ('missing',)
 
1026
        missing_key = (b'missing',)
1026
1027
        index = self.make_index(ref_lists=2, nodes=[
1027
 
            (('key',), 'value', ([], [missing_key]))])
 
1028
            ((b'key',), b'value', ([], [missing_key]))])
1028
1029
        self.assertEqual(set([]), index.external_references(0))
1029
1030
        self.assertEqual({missing_key}, index.external_references(1))
1030
1031
 
1031
1032
    def test_external_references_two_records(self):
1032
1033
        index = self.make_index(ref_lists=1, nodes=[
1033
 
            (('key-1',), 'value', ([('key-2',)],)),
1034
 
            (('key-2',), 'value', ([],)),
 
1034
            ((b'key-1',), b'value', ([(b'key-2',)],)),
 
1035
            ((b'key-2',), b'value', ([],)),
1035
1036
            ])
1036
1037
        self.assertEqual(set([]), index.external_references(0))
1037
1038
 
1038
1039
    def test__find_ancestors(self):
1039
 
        key1 = ('key-1',)
1040
 
        key2 = ('key-2',)
 
1040
        key1 = (b'key-1',)
 
1041
        key2 = (b'key-2',)
1041
1042
        index = self.make_index(ref_lists=1, key_elements=1, nodes=[
1042
 
            (key1, 'value', ([key2],)),
1043
 
            (key2, 'value', ([],)),
 
1043
            (key1, b'value', ([key2],)),
 
1044
            (key2, b'value', ([],)),
1044
1045
            ])
1045
1046
        parent_map = {}
1046
1047
        missing_keys = set()
1055
1056
        self.assertEqual(set(), search_keys)
1056
1057
 
1057
1058
    def test__find_ancestors_w_missing(self):
1058
 
        key1 = ('key-1',)
1059
 
        key2 = ('key-2',)
1060
 
        key3 = ('key-3',)
 
1059
        key1 = (b'key-1',)
 
1060
        key2 = (b'key-2',)
 
1061
        key3 = (b'key-3',)
1061
1062
        index = self.make_index(ref_lists=1, key_elements=1, nodes=[
1062
 
            (key1, 'value', ([key2],)),
1063
 
            (key2, 'value', ([],)),
 
1063
            (key1, b'value', ([key2],)),
 
1064
            (key2, b'value', ([],)),
1064
1065
            ])
1065
1066
        parent_map = {}
1066
1067
        missing_keys = set()
1071
1072
        self.assertEqual(set(), search_keys)
1072
1073
 
1073
1074
    def test__find_ancestors_dont_search_known(self):
1074
 
        key1 = ('key-1',)
1075
 
        key2 = ('key-2',)
1076
 
        key3 = ('key-3',)
 
1075
        key1 = (b'key-1',)
 
1076
        key2 = (b'key-2',)
 
1077
        key3 = (b'key-3',)
1077
1078
        index = self.make_index(ref_lists=1, key_elements=1, nodes=[
1078
 
            (key1, 'value', ([key2],)),
1079
 
            (key2, 'value', ([key3],)),
1080
 
            (key3, 'value', ([],)),
 
1079
            (key1, b'value', ([key2],)),
 
1080
            (key2, b'value', ([key3],)),
 
1081
            (key3, b'value', ([],)),
1081
1082
            ])
1082
1083
        # We already know about key2, so we won't try to search for key3
1083
1084
        parent_map = {key2: (key3,)}
1109
1110
        size = trans.put_file(name, stream)
1110
1111
        return _mod_index.GraphIndex(trans, name, size)
1111
1112
 
1112
 
    def make_combined_index_with_missing(self, missing=['1', '2']):
 
1113
    def make_combined_index_with_missing(self, missing=[b'1', b'2']):
1113
1114
        """Create a CombinedGraphIndex which will have missing indexes.
1114
1115
 
1115
1116
        This creates a CGI which thinks it has 2 indexes, however they have
1119
1120
        :param missing: The underlying indexes to delete
1120
1121
        :return: (CombinedGraphIndex, reload_counter)
1121
1122
        """
1122
 
        idx1 = self.make_index('1', nodes=[(('1',), '', ())])
1123
 
        idx2 = self.make_index('2', nodes=[(('2',), '', ())])
 
1123
        idx1 = self.make_index('1', nodes=[((b'1',), b'', ())])
 
1124
        idx2 = self.make_index('2', nodes=[((b'2',), b'', ())])
1124
1125
        idx3 = self.make_index('3', nodes=[
1125
 
            (('1',), '', ()),
1126
 
            (('2',), '', ())])
 
1126
            ((b'1',), b'', ()),
 
1127
            ((b'2',), b'', ())])
1127
1128
 
1128
1129
        # total_reloads, num_changed, num_unchanged
1129
1130
        reload_counter = [0, 0, 0]
1149
1150
 
1150
1151
    def test_add_index(self):
1151
1152
        idx = _mod_index.CombinedGraphIndex([])
1152
 
        idx1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
 
1153
        idx1 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
1153
1154
        idx.insert_index(0, idx1)
1154
 
        self.assertEqual([(idx1, ('key', ), '')],
 
1155
        self.assertEqual([(idx1, (b'key', ), b'')],
1155
1156
                         list(idx.iter_all_entries()))
1156
1157
 
1157
1158
    def test_clear_cache(self):
1170
1171
                return self._index.clear_cache()
1171
1172
 
1172
1173
        idx = _mod_index.CombinedGraphIndex([])
1173
 
        idx1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
 
1174
        idx1 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
1174
1175
        idx.insert_index(0, ClearCacheProxy(idx1))
1175
 
        idx2 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
 
1176
        idx2 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
1176
1177
        idx.insert_index(1, ClearCacheProxy(idx2))
1177
1178
        # CombinedGraphIndex should call 'clear_cache()' on all children
1178
1179
        idx.clear_cache()
1188
1189
        self.assertEqual([], list(idx.iter_all_entries()))
1189
1190
 
1190
1191
    def test_iter_all_entries_simple(self):
1191
 
        idx1 = self.make_index('name', nodes=[(('name', ), 'data', ())])
 
1192
        idx1 = self.make_index('name', nodes=[((b'name', ), b'data', ())])
1192
1193
        idx = _mod_index.CombinedGraphIndex([idx1])
1193
 
        self.assertEqual([(idx1, ('name', ), 'data')],
 
1194
        self.assertEqual([(idx1, (b'name', ), b'data')],
1194
1195
            list(idx.iter_all_entries()))
1195
1196
 
1196
1197
    def test_iter_all_entries_two_indices(self):
1197
 
        idx1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1198
 
        idx2 = self.make_index('name2', nodes=[(('2', ), '', ())])
 
1198
        idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
 
1199
        idx2 = self.make_index('name2', nodes=[((b'2', ), b'', ())])
1199
1200
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1200
 
        self.assertEqual([(idx1, ('name', ), 'data'),
1201
 
                          (idx2, ('2', ), '')],
 
1201
        self.assertEqual([(idx1, (b'name', ), b'data'),
 
1202
                          (idx2, (b'2', ), b'')],
1202
1203
                         list(idx.iter_all_entries()))
1203
1204
 
1204
1205
    def test_iter_entries_two_indices_dup_key(self):
1205
 
        idx1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1206
 
        idx2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
 
1206
        idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
 
1207
        idx2 = self.make_index('name2', nodes=[((b'name', ), b'data', ())])
1207
1208
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1208
 
        self.assertEqual([(idx1, ('name', ), 'data')],
1209
 
                         list(idx.iter_entries([('name', )])))
 
1209
        self.assertEqual([(idx1, (b'name', ), b'data')],
 
1210
                         list(idx.iter_entries([(b'name', )])))
1210
1211
 
1211
1212
    def test_iter_all_entries_two_indices_dup_key(self):
1212
 
        idx1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1213
 
        idx2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
 
1213
        idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
 
1214
        idx2 = self.make_index('name2', nodes=[((b'name', ), b'data', ())])
1214
1215
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1215
 
        self.assertEqual([(idx1, ('name', ), 'data')],
 
1216
        self.assertEqual([(idx1, (b'name', ), b'data')],
1216
1217
                         list(idx.iter_all_entries()))
1217
1218
 
1218
1219
    def test_iter_key_prefix_2_key_element_refs(self):
1219
1220
        idx1 = self.make_index('1', 1, key_elements=2, nodes=[
1220
 
                (('name', 'fin1'), 'data', ([('ref', 'erence')], ))])
1221
 
        idx2 = self.make_index('2', 1, key_elements=2, nodes=[
1222
 
                (('name', 'fin2'), 'beta', ([], )),
1223
 
                (('ref', 'erence'), 'refdata', ([], ))])
 
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', ([], ))])
1224
1225
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1225
 
        self.assertEqual({(idx1, ('name', 'fin1'), 'data',
1226
 
                               ((('ref', 'erence'),),)),
1227
 
                              (idx2, ('ref', 'erence'), 'refdata', ((), ))},
1228
 
                         set(idx.iter_entries_prefix([('name', 'fin1'),
1229
 
                                                        ('ref', 'erence')])))
1230
 
        self.assertEqual({(idx1, ('name', 'fin1'), 'data',
1231
 
                               ((('ref', 'erence'),),)),
1232
 
                              (idx2, ('name', 'fin2'), 'beta', ((), ))},
1233
 
                         set(idx.iter_entries_prefix([('name', None)])))
 
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)])))
1234
1235
 
1235
1236
    def test_iter_nothing_empty(self):
1236
1237
        idx = _mod_index.CombinedGraphIndex([])
1242
1243
        self.assertEqual([], list(idx.iter_entries([])))
1243
1244
 
1244
1245
    def test_iter_all_keys(self):
1245
 
        idx1 = self.make_index('1', 1, nodes=[(('name', ), 'data',
1246
 
                                               ([('ref', )], ))])
1247
 
        idx2 = self.make_index('2', 1, nodes=[(('ref', ), 'refdata', ((), ))])
 
1246
        idx1 = self.make_index('1', 1, nodes=[((b'name', ), b'data',
 
1247
                                               ([(b'ref', )], ))])
 
1248
        idx2 = self.make_index('2', 1, nodes=[((b'ref', ), b'refdata', ((), ))])
1248
1249
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1249
 
        self.assertEqual({(idx1, ('name', ), 'data', ((('ref', ), ), )),
1250
 
                              (idx2, ('ref', ), 'refdata', ((), ))},
1251
 
                         set(idx.iter_entries([('name', ), ('ref', )])))
 
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', )])))
1252
1253
 
1253
1254
    def test_iter_all_keys_dup_entry(self):
1254
 
        idx1 = self.make_index('1', 1, nodes=[(('name', ), 'data',
1255
 
                                                 ([('ref', )], )),
1256
 
                                                (('ref', ), 'refdata', ([], ))])
1257
 
        idx2 = self.make_index('2', 1, nodes=[(('ref', ), 'refdata', ([], ))])
 
1255
        idx1 = self.make_index('1', 1, nodes=[((b'name', ), b'data',
 
1256
                                                 ([(b'ref', )], )),
 
1257
                                                ((b'ref', ), b'refdata', ([], ))])
 
1258
        idx2 = self.make_index('2', 1, nodes=[((b'ref', ), b'refdata', ([], ))])
1258
1259
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1259
 
        self.assertEqual({(idx1, ('name', ), 'data', ((('ref',),),)),
1260
 
                              (idx1, ('ref', ), 'refdata', ((), ))},
1261
 
                         set(idx.iter_entries([('name', ), ('ref', )])))
 
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', )])))
1262
1263
 
1263
1264
    def test_iter_missing_entry_empty(self):
1264
1265
        idx = _mod_index.CombinedGraphIndex([])
1267
1268
    def test_iter_missing_entry_one_index(self):
1268
1269
        idx1 = self.make_index('1')
1269
1270
        idx = _mod_index.CombinedGraphIndex([idx1])
1270
 
        self.assertEqual([], list(idx.iter_entries([('a', )])))
 
1271
        self.assertEqual([], list(idx.iter_entries([(b'a', )])))
1271
1272
 
1272
1273
    def test_iter_missing_entry_two_index(self):
1273
1274
        idx1 = self.make_index('1')
1276
1277
        self.assertEqual([], list(idx.iter_entries([('a', )])))
1277
1278
 
1278
1279
    def test_iter_entry_present_one_index_only(self):
1279
 
        idx1 = self.make_index('1', nodes=[(('key', ), '', ())])
 
1280
        idx1 = self.make_index('1', nodes=[((b'key', ), b'', ())])
1280
1281
        idx2 = self.make_index('2', nodes=[])
1281
1282
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1282
 
        self.assertEqual([(idx1, ('key', ), '')],
1283
 
                         list(idx.iter_entries([('key', )])))
 
1283
        self.assertEqual([(idx1, (b'key', ), b'')],
 
1284
                         list(idx.iter_entries([(b'key', )])))
1284
1285
        # and in the other direction
1285
1286
        idx = _mod_index.CombinedGraphIndex([idx2, idx1])
1286
 
        self.assertEqual([(idx1, ('key', ), '')],
1287
 
                         list(idx.iter_entries([('key', )])))
 
1287
        self.assertEqual([(idx1, (b'key', ), b'')],
 
1288
                         list(idx.iter_entries([(b'key', )])))
1288
1289
 
1289
1290
    def test_key_count_empty(self):
1290
1291
        idx1 = self.make_index('1', nodes=[])
1294
1295
 
1295
1296
    def test_key_count_sums_index_keys(self):
1296
1297
        idx1 = self.make_index('1', nodes=[
1297
 
            (('1',), '', ()),
1298
 
            (('2',), '', ())])
1299
 
        idx2 = self.make_index('2', nodes=[(('1',), '', ())])
 
1298
            ((b'1',), b'', ()),
 
1299
            ((b'2',), b'', ())])
 
1300
        idx2 = self.make_index('2', nodes=[((b'1',), b'', ())])
1300
1301
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1301
1302
        self.assertEqual(3, idx.key_count())
1302
1303
 
1303
1304
    def test_validate_bad_child_index_errors(self):
1304
1305
        trans = self.get_transport()
1305
 
        trans.put_bytes('name', "not an index\n")
 
1306
        trans.put_bytes('name', b"not an index\n")
1306
1307
        idx1 = _mod_index.GraphIndex(trans, 'name', 13)
1307
1308
        idx = _mod_index.CombinedGraphIndex([idx1])
1308
1309
        self.assertRaises(_mod_index.BadIndexFormatSignature, idx.validate)
1327
1328
        # still fail. This is mostly to test we don't get stuck in an infinite
1328
1329
        # loop trying to reload
1329
1330
        idx, reload_counter = self.make_combined_index_with_missing(
1330
 
            ['1', '2', '3'])
 
1331
            [b'1', b'2', b'3'])
1331
1332
        self.assertRaises(errors.NoSuchFile, idx.key_count)
1332
1333
        self.assertEqual([2, 1, 1], reload_counter)
1333
1334
 
1334
1335
    def test_iter_entries_reloads(self):
1335
1336
        index, reload_counter = self.make_combined_index_with_missing()
1336
 
        result = list(index.iter_entries([('1',), ('2',), ('3',)]))
 
1337
        result = list(index.iter_entries([(b'1',), (b'2',), (b'3',)]))
1337
1338
        index3 = index._indices[0]
1338
 
        self.assertEqual([(index3, ('1',), ''), (index3, ('2',), '')],
 
1339
        self.assertEqual([(index3, (b'1',), b''), (index3, (b'2',), b'')],
1339
1340
                         result)
1340
1341
        self.assertEqual([1, 1, 0], reload_counter)
1341
1342
 
1344
1345
        # through
1345
1346
        index, reload_counter = self.make_combined_index_with_missing(['2'])
1346
1347
        index1, index2 = index._indices
1347
 
        result = list(index.iter_entries([('1',), ('2',), ('3',)]))
 
1348
        result = list(index.iter_entries([(b'1',), (b'2',), (b'3',)]))
1348
1349
        index3 = index._indices[0]
1349
 
        # We had already yielded '1', so we just go on to the next, we should
1350
 
        # not yield '1' twice.
1351
 
        self.assertEqual([(index1, ('1',), ''), (index3, ('2',), '')],
 
1350
        # We had already yielded b'1', so we just go on to the next, we should
 
1351
        # not yield b'1' twice.
 
1352
        self.assertEqual([(index1, (b'1',), b''), (index3, (b'2',), b'')],
1352
1353
                         result)
1353
1354
        self.assertEqual([1, 1, 0], reload_counter)
1354
1355
 
1368
1369
        index, reload_counter = self.make_combined_index_with_missing()
1369
1370
        result = list(index.iter_all_entries())
1370
1371
        index3 = index._indices[0]
1371
 
        self.assertEqual([(index3, ('1',), ''), (index3, ('2',), '')],
 
1372
        self.assertEqual([(index3, (b'1',), b''), (index3, (b'2',), b'')],
1372
1373
                         result)
1373
1374
        self.assertEqual([1, 1, 0], reload_counter)
1374
1375
 
1379
1380
        index3 = index._indices[0]
1380
1381
        # We had already yielded '1', so we just go on to the next, we should
1381
1382
        # not yield '1' twice.
1382
 
        self.assertEqual([(index1, ('1',), ''), (index3, ('2',), '')],
 
1383
        self.assertEqual([(index1, (b'1',), b''), (index3, (b'2',), b'')],
1383
1384
                         result)
1384
1385
        self.assertEqual([1, 1, 0], reload_counter)
1385
1386
 
1390
1391
 
1391
1392
    def test_iter_all_entries_reloads_and_fails(self):
1392
1393
        index, reload_counter = self.make_combined_index_with_missing(
1393
 
                                    ['1', '2', '3'])
 
1394
                                    [b'1', b'2', b'3'])
1394
1395
        self.assertListRaises(errors.NoSuchFile, index.iter_all_entries)
1395
1396
 
1396
1397
    def test_iter_entries_prefix_reloads(self):
1397
1398
        index, reload_counter = self.make_combined_index_with_missing()
1398
 
        result = list(index.iter_entries_prefix([('1',)]))
 
1399
        result = list(index.iter_entries_prefix([(b'1',)]))
1399
1400
        index3 = index._indices[0]
1400
 
        self.assertEqual([(index3, ('1',), '')], result)
 
1401
        self.assertEqual([(index3, (b'1',), b'')], result)
1401
1402
        self.assertEqual([1, 1, 0], reload_counter)
1402
1403
 
1403
1404
    def test_iter_entries_prefix_reloads_midway(self):
1404
 
        index, reload_counter = self.make_combined_index_with_missing(['2'])
 
1405
        index, reload_counter = self.make_combined_index_with_missing([b'2'])
1405
1406
        index1, index2 = index._indices
1406
 
        result = list(index.iter_entries_prefix([('1',)]))
 
1407
        result = list(index.iter_entries_prefix([(b'1',)]))
1407
1408
        index3 = index._indices[0]
1408
 
        # We had already yielded '1', so we just go on to the next, we should
1409
 
        # not yield '1' twice.
1410
 
        self.assertEqual([(index1, ('1',), '')], result)
 
1409
        # We had already yielded b'1', so we just go on to the next, we should
 
1410
        # not yield b'1' twice.
 
1411
        self.assertEqual([(index1, (b'1',), b'')], result)
1411
1412
        self.assertEqual([1, 1, 0], reload_counter)
1412
1413
 
1413
1414
    def test_iter_entries_prefix_no_reload(self):
1414
1415
        index, reload_counter = self.make_combined_index_with_missing()
1415
1416
        index._reload_func = None
1416
1417
        self.assertListRaises(errors.NoSuchFile, index.iter_entries_prefix,
1417
 
                                                 [('1',)])
 
1418
                                                 [(b'1',)])
1418
1419
 
1419
1420
    def test_iter_entries_prefix_reloads_and_fails(self):
1420
1421
        index, reload_counter = self.make_combined_index_with_missing(
1421
 
                                    ['1', '2', '3'])
 
1422
                                    [b'1', b'2', b'3'])
1422
1423
        self.assertListRaises(errors.NoSuchFile, index.iter_entries_prefix,
1423
 
                                                 [('1',)])
 
1424
                                                 [(b'1',)])
1424
1425
 
1425
1426
 
1426
1427
    def make_index_with_simple_nodes(self, name, num_nodes=1):
1429
1430
        Nodes will have a value of '' and no references.
1430
1431
        """
1431
1432
        nodes = [
1432
 
            (('index-%s-key-%s' % (name, n),), '', ())
 
1433
            ((('index-%s-key-%s' % (name, n)).encode('ascii'),), b'', ())
1433
1434
            for n in range(1, num_nodes+1)]
1434
1435
        return self.make_index('index-%s' % name, 0, nodes=nodes)
1435
1436
 
1437
1438
        # Four indices: [key1] in idx1, [key2,key3] in idx2, [] in idx3,
1438
1439
        # [key4] in idx4.
1439
1440
        idx = _mod_index.CombinedGraphIndex([])
1440
 
        idx.insert_index(0, self.make_index_with_simple_nodes('1'), '1')
1441
 
        idx.insert_index(1, self.make_index_with_simple_nodes('2'), '2')
1442
 
        idx.insert_index(2, self.make_index_with_simple_nodes('3'), '3')
1443
 
        idx.insert_index(3, self.make_index_with_simple_nodes('4'), '4')
 
1441
        idx.insert_index(0, self.make_index_with_simple_nodes('1'), b'1')
 
1442
        idx.insert_index(1, self.make_index_with_simple_nodes('2'), b'2')
 
1443
        idx.insert_index(2, self.make_index_with_simple_nodes('3'), b'3')
 
1444
        idx.insert_index(3, self.make_index_with_simple_nodes('4'), b'4')
1444
1445
        idx1, idx2, idx3, idx4 = idx._indices
1445
1446
        # Query a key from idx4 and idx2.
1446
1447
        self.assertLength(2, list(idx.iter_entries(
1447
 
            [('index-4-key-1',), ('index-2-key-1',)])))
 
1448
            [(b'index-4-key-1',), (b'index-2-key-1',)])))
1448
1449
        # Now idx2 and idx4 should be moved to the front (and idx1 should
1449
1450
        # still be before idx3).
1450
1451
        self.assertEqual([idx2, idx4, idx1, idx3], idx._indices)
1451
 
        self.assertEqual(['2', '4', '1', '3'], idx._index_names)
 
1452
        self.assertEqual([b'2', b'4', b'1', b'3'], idx._index_names)
1452
1453
 
1453
1454
    def test_reorder_propagates_to_siblings(self):
1454
1455
        # Two CombinedGraphIndex objects, with the same number of indicies with
1486
1487
        self.assertRaises(errors.NoSuchFile, idx.validate)
1487
1488
 
1488
1489
    def test_find_ancestors_across_indexes(self):
1489
 
        key1 = ('key-1',)
1490
 
        key2 = ('key-2',)
1491
 
        key3 = ('key-3',)
1492
 
        key4 = ('key-4',)
 
1490
        key1 = (b'key-1',)
 
1491
        key2 = (b'key-2',)
 
1492
        key3 = (b'key-3',)
 
1493
        key4 = (b'key-4',)
1493
1494
        index1 = self.make_index('12', ref_lists=1, nodes=[
1494
 
            (key1, 'value', ([],)),
1495
 
            (key2, 'value', ([key1],)),
 
1495
            (key1, b'value', ([],)),
 
1496
            (key2, b'value', ([key1],)),
1496
1497
            ])
1497
1498
        index2 = self.make_index('34', ref_lists=1, nodes=[
1498
 
            (key3, 'value', ([key2],)),
1499
 
            (key4, 'value', ([key3],)),
 
1499
            (key3, b'value', ([key2],)),
 
1500
            (key4, b'value', ([key3],)),
1500
1501
            ])
1501
1502
        c_index = _mod_index.CombinedGraphIndex([index1, index2])
1502
1503
        parent_map, missing_keys = c_index.find_ancestry([key1], 0)
1510
1511
        self.assertEqual(set(), missing_keys)
1511
1512
 
1512
1513
    def test_find_ancestors_missing_keys(self):
1513
 
        key1 = ('key-1',)
1514
 
        key2 = ('key-2',)
1515
 
        key3 = ('key-3',)
1516
 
        key4 = ('key-4',)
 
1514
        key1 = (b'key-1',)
 
1515
        key2 = (b'key-2',)
 
1516
        key3 = (b'key-3',)
 
1517
        key4 = (b'key-4',)
1517
1518
        index1 = self.make_index('12', ref_lists=1, nodes=[
1518
 
            (key1, 'value', ([],)),
1519
 
            (key2, 'value', ([key1],)),
 
1519
            (key1, b'value', ([],)),
 
1520
            (key2, b'value', ([key1],)),
1520
1521
            ])
1521
1522
        index2 = self.make_index('34', ref_lists=1, nodes=[
1522
 
            (key3, 'value', ([key2],)),
 
1523
            (key3, b'value', ([key2],)),
1523
1524
            ])
1524
1525
        c_index = _mod_index.CombinedGraphIndex([index1, index2])
1525
1526
        # Searching for a key which is actually not present at all should
1530
1531
 
1531
1532
    def test_find_ancestors_no_indexes(self):
1532
1533
        c_index = _mod_index.CombinedGraphIndex([])
1533
 
        key1 = ('key-1',)
 
1534
        key1 = (b'key-1',)
1534
1535
        parent_map, missing_keys = c_index.find_ancestry([key1], 0)
1535
1536
        self.assertEqual({}, parent_map)
1536
1537
        self.assertEqual({key1}, missing_keys)
1537
1538
 
1538
1539
    def test_find_ancestors_ghost_parent(self):
1539
 
        key1 = ('key-1',)
1540
 
        key2 = ('key-2',)
1541
 
        key3 = ('key-3',)
1542
 
        key4 = ('key-4',)
 
1540
        key1 = (b'key-1',)
 
1541
        key2 = (b'key-2',)
 
1542
        key3 = (b'key-3',)
 
1543
        key4 = (b'key-4',)
1543
1544
        index1 = self.make_index('12', ref_lists=1, nodes=[
1544
 
            (key1, 'value', ([],)),
1545
 
            (key2, 'value', ([key1],)),
 
1545
            (key1, b'value', ([],)),
 
1546
            (key2, b'value', ([key1],)),
1546
1547
            ])
1547
1548
        index2 = self.make_index('34', ref_lists=1, nodes=[
1548
 
            (key4, 'value', ([key2, key3],)),
 
1549
            (key4, b'value', ([key2, key3],)),
1549
1550
            ])
1550
1551
        c_index = _mod_index.CombinedGraphIndex([index1, index2])
1551
1552
        # Searching for a key which is actually not present at all should
1559
1560
        idx = self.make_index('test', ref_lists=1, key_elements=1, nodes=[])
1560
1561
        parent_map = {}
1561
1562
        missing_keys = set()
1562
 
        search_keys = idx._find_ancestors([('one',), ('two',)], 0, parent_map,
 
1563
        search_keys = idx._find_ancestors([(b'one',), (b'two',)], 0, parent_map,
1563
1564
                                          missing_keys)
1564
1565
        self.assertEqual(set(), search_keys)
1565
1566
        self.assertEqual({}, parent_map)
1566
 
        self.assertEqual({('one',), ('two',)}, missing_keys)
 
1567
        self.assertEqual({(b'one',), (b'two',)}, missing_keys)
1567
1568
 
1568
1569
 
1569
1570
class TestInMemoryGraphIndex(tests.TestCaseWithMemoryTransport):
1575
1576
 
1576
1577
    def test_add_nodes_no_refs(self):
1577
1578
        index = self.make_index(0)
1578
 
        index.add_nodes([(('name', ), 'data')])
1579
 
        index.add_nodes([(('name2', ), ''), (('name3', ), '')])
 
1579
        index.add_nodes([((b'name', ), b'data')])
 
1580
        index.add_nodes([((b'name2', ), b''), ((b'name3', ), b'')])
1580
1581
        self.assertEqual({
1581
 
            (index, ('name', ), 'data'),
1582
 
            (index, ('name2', ), ''),
1583
 
            (index, ('name3', ), ''),
 
1582
            (index, (b'name', ), b'data'),
 
1583
            (index, (b'name2', ), b''),
 
1584
            (index, (b'name3', ), b''),
1584
1585
            }, set(index.iter_all_entries()))
1585
1586
 
1586
1587
    def test_add_nodes(self):
1587
1588
        index = self.make_index(1)
1588
 
        index.add_nodes([(('name', ), 'data', ([],))])
1589
 
        index.add_nodes([(('name2', ), '', ([],)), (('name3', ), '', ([('r', )],))])
 
1589
        index.add_nodes([((b'name', ), b'data', ([],))])
 
1590
        index.add_nodes([((b'name2', ), b'', ([],)), ((b'name3', ), b'', ([(b'r', )],))])
1590
1591
        self.assertEqual({
1591
 
            (index, ('name', ), 'data', ((),)),
1592
 
            (index, ('name2', ), '', ((),)),
1593
 
            (index, ('name3', ), '', ((('r', ), ), )),
 
1592
            (index, (b'name', ), b'data', ((),)),
 
1593
            (index, (b'name2', ), b'', ((),)),
 
1594
            (index, (b'name3', ), b'', (((b'r', ), ), )),
1594
1595
            }, set(index.iter_all_entries()))
1595
1596
 
1596
1597
    def test_iter_all_entries_empty(self):
1598
1599
        self.assertEqual([], list(index.iter_all_entries()))
1599
1600
 
1600
1601
    def test_iter_all_entries_simple(self):
1601
 
        index = self.make_index(nodes=[(('name', ), 'data')])
1602
 
        self.assertEqual([(index, ('name', ), 'data')],
 
1602
        index = self.make_index(nodes=[((b'name', ), b'data')])
 
1603
        self.assertEqual([(index, (b'name', ), b'data')],
1603
1604
            list(index.iter_all_entries()))
1604
1605
 
1605
1606
    def test_iter_all_entries_references(self):
1606
1607
        index = self.make_index(1, nodes=[
1607
 
            (('name', ), 'data', ([('ref', )], )),
1608
 
            (('ref', ), 'refdata', ([], ))])
1609
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref', ),),)),
1610
 
            (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', ((), ))},
1611
1612
            set(index.iter_all_entries()))
1612
1613
 
1613
1614
    def test_iteration_absent_skipped(self):
1614
1615
        index = self.make_index(1, nodes=[
1615
 
            (('name', ), 'data', ([('ref', )], ))])
1616
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),))},
 
1616
            ((b'name', ), b'data', ([(b'ref', )], ))])
 
1617
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
1617
1618
            set(index.iter_all_entries()))
1618
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),))},
1619
 
            set(index.iter_entries([('name', )])))
1620
 
        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', )])))
1621
1622
 
1622
1623
    def test_iter_all_keys(self):
1623
1624
        index = self.make_index(1, nodes=[
1624
 
            (('name', ), 'data', ([('ref', )], )),
1625
 
            (('ref', ), 'refdata', ([], ))])
1626
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
1627
 
            (index, ('ref', ), 'refdata', ((), ))},
1628
 
            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', )])))
1629
1630
 
1630
1631
    def test_iter_key_prefix_1_key_element_no_refs(self):
1631
1632
        index = self.make_index( nodes=[
1632
 
            (('name', ), 'data'),
1633
 
            (('ref', ), 'refdata')])
1634
 
        self.assertEqual({(index, ('name', ), 'data'),
1635
 
            (index, ('ref', ), 'refdata')},
1636
 
            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', )])))
1637
1638
 
1638
1639
    def test_iter_key_prefix_1_key_element_refs(self):
1639
1640
        index = self.make_index(1, nodes=[
1640
 
            (('name', ), 'data', ([('ref', )], )),
1641
 
            (('ref', ), 'refdata', ([], ))])
1642
 
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
1643
 
            (index, ('ref', ), 'refdata', ((), ))},
1644
 
            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', )])))
1645
1646
 
1646
1647
    def test_iter_key_prefix_2_key_element_no_refs(self):
1647
1648
        index = self.make_index(key_elements=2, nodes=[
1648
 
            (('name', 'fin1'), 'data'),
1649
 
            (('name', 'fin2'), 'beta'),
1650
 
            (('ref', 'erence'), 'refdata')])
1651
 
        self.assertEqual({(index, ('name', 'fin1'), 'data'),
1652
 
            (index, ('ref', 'erence'), 'refdata')},
1653
 
            set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1654
 
        self.assertEqual({(index, ('name', 'fin1'), 'data'),
1655
 
            (index, ('name', 'fin2'), 'beta')},
1656
 
            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)])))
1657
1658
 
1658
1659
    def test_iter_key_prefix_2_key_element_refs(self):
1659
1660
        index = self.make_index(1, key_elements=2, nodes=[
1660
 
            (('name', 'fin1'), 'data', ([('ref', 'erence')], )),
1661
 
            (('name', 'fin2'), 'beta', ([], )),
1662
 
            (('ref', 'erence'), 'refdata', ([], ))])
1663
 
        self.assertEqual({(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1664
 
            (index, ('ref', 'erence'), 'refdata', ((), ))},
1665
 
            set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1666
 
        self.assertEqual({(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1667
 
            (index, ('name', 'fin2'), 'beta', ((), ))},
1668
 
            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)])))
1669
1670
 
1670
1671
    def test_iter_nothing_empty(self):
1671
1672
        index = self.make_index()
1673
1674
 
1674
1675
    def test_iter_missing_entry_empty(self):
1675
1676
        index = self.make_index()
1676
 
        self.assertEqual([], list(index.iter_entries(['a'])))
 
1677
        self.assertEqual([], list(index.iter_entries([b'a'])))
1677
1678
 
1678
1679
    def test_key_count_empty(self):
1679
1680
        index = self.make_index()
1680
1681
        self.assertEqual(0, index.key_count())
1681
1682
 
1682
1683
    def test_key_count_one(self):
1683
 
        index = self.make_index(nodes=[(('name', ), '')])
 
1684
        index = self.make_index(nodes=[((b'name', ), b'')])
1684
1685
        self.assertEqual(1, index.key_count())
1685
1686
 
1686
1687
    def test_key_count_two(self):
1687
 
        index = self.make_index(nodes=[(('name', ), ''), (('foo', ), '')])
 
1688
        index = self.make_index(nodes=[((b'name', ), b''), ((b'foo', ), b'')])
1688
1689
        self.assertEqual(2, index.key_count())
1689
1690
 
1690
1691
    def test_validate_empty(self):
1692
1693
        index.validate()
1693
1694
 
1694
1695
    def test_validate_no_refs_content(self):
1695
 
        index = self.make_index(nodes=[(('key', ), 'value')])
 
1696
        index = self.make_index(nodes=[((b'key', ), b'value')])
1696
1697
        index.validate()
1697
1698
 
1698
1699
 
1707
1708
        else:
1708
1709
            add_nodes_callback = None
1709
1710
        adapter = _mod_index.GraphIndexPrefixAdapter(
1710
 
            result, ('prefix', ), key_elements - 1,
 
1711
            result, (b'prefix', ), key_elements - 1,
1711
1712
            add_nodes_callback=add_nodes_callback)
1712
1713
        return result, adapter
1713
1714
 
1714
1715
    def test_add_node(self):
1715
1716
        index, adapter = self.make_index(add_callback=True)
1716
 
        adapter.add_node(('key',), 'value', ((('ref',),),))
1717
 
        self.assertEqual({(index, ('prefix', 'key'), 'value',
1718
 
                               ((('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'),),))},
1719
1720
            set(index.iter_all_entries()))
1720
1721
 
1721
1722
    def test_add_nodes(self):
1722
1723
        index, adapter = self.make_index(add_callback=True)
1723
1724
        adapter.add_nodes((
1724
 
            (('key',), 'value', ((('ref',),),)),
1725
 
            (('key2',), 'value2', ((),)),
 
1725
            ((b'key',), b'value', (((b'ref',),),)),
 
1726
            ((b'key2',), b'value2', ((),)),
1726
1727
            ))
1727
1728
        self.assertEqual({
1728
 
            (index, ('prefix', 'key2'), 'value2', ((),)),
1729
 
            (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'),),))
1730
1731
            },
1731
1732
            set(index.iter_all_entries()))
1732
1733
 
1733
1734
    def test_construct(self):
1734
1735
        idx = _mod_index.InMemoryGraphIndex()
1735
 
        adapter = _mod_index.GraphIndexPrefixAdapter(idx, ('prefix', ), 1)
 
1736
        adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1)
1736
1737
 
1737
1738
    def test_construct_with_callback(self):
1738
1739
        idx = _mod_index.InMemoryGraphIndex()
1739
 
        adapter = _mod_index.GraphIndexPrefixAdapter(idx, ('prefix', ), 1,
 
1740
        adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1,
1740
1741
                                                idx.add_nodes)
1741
1742
 
1742
1743
    def test_iter_all_entries_cross_prefix_map_errors(self):
1743
1744
        index, adapter = self.make_index(nodes=[
1744
 
            (('prefix', 'key1'), 'data1', ((('prefixaltered', 'key2'),),))])
 
1745
            ((b'prefix', b'key1'), b'data1', (((b'prefixaltered', b'key2'),),))])
1745
1746
        self.assertRaises(_mod_index.BadIndexData, list, adapter.iter_all_entries())
1746
1747
 
1747
1748
    def test_iter_all_entries(self):
1748
1749
        index, adapter = self.make_index(nodes=[
1749
 
            (('notprefix', 'key1'), 'data', ((), )),
1750
 
            (('prefix', 'key1'), 'data1', ((), )),
1751
 
            (('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1752
 
        self.assertEqual({(index, ('key1', ), 'data1', ((),)),
1753
 
            (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',),),))},
1754
1755
            set(adapter.iter_all_entries()))
1755
1756
 
1756
1757
    def test_iter_entries(self):
1757
1758
        index, adapter = self.make_index(nodes=[
1758
 
            (('notprefix', 'key1'), 'data', ((), )),
1759
 
            (('prefix', 'key1'), 'data1', ((), )),
1760
 
            (('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'),),))])
1761
1762
        # ask for many - get all
1762
 
        self.assertEqual({(index, ('key1', ), 'data1', ((),)),
1763
 
            (index, ('key2', ), 'data2', ((('key1', ),),))},
1764
 
            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', )])))
1765
1766
        # ask for one, get one
1766
 
        self.assertEqual({(index, ('key1', ), 'data1', ((),))},
1767
 
            set(adapter.iter_entries([('key1', )])))
 
1767
        self.assertEqual({(index, (b'key1', ), b'data1', ((),))},
 
1768
            set(adapter.iter_entries([(b'key1', )])))
1768
1769
        # ask for missing, get none
1769
1770
        self.assertEqual(set(),
1770
 
            set(adapter.iter_entries([('key3', )])))
 
1771
            set(adapter.iter_entries([(b'key3', )])))
1771
1772
 
1772
1773
    def test_iter_entries_prefix(self):
1773
1774
        index, adapter = self.make_index(key_elements=3, nodes=[
1774
 
            (('notprefix', 'foo', 'key1'), 'data', ((), )),
1775
 
            (('prefix', 'prefix2', 'key1'), 'data1', ((), )),
1776
 
            (('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'),),))])
1777
1778
        # ask for a prefix, get the results for just that prefix, adjusted.
1778
 
        self.assertEqual({(index, ('prefix2', 'key1', ), 'data1', ((),)),
1779
 
            (index, ('prefix2', 'key2', ), 'data2', ((('prefix2', 'key1', ),),))},
1780
 
            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)])))
1781
1782
 
1782
1783
    def test_key_count_no_matching_keys(self):
1783
1784
        index, adapter = self.make_index(nodes=[
1784
 
            (('notprefix', 'key1'), 'data', ((), ))])
 
1785
            ((b'notprefix', b'key1'), b'data', ((), ))])
1785
1786
        self.assertEqual(0, adapter.key_count())
1786
1787
 
1787
1788
    def test_key_count_some_keys(self):
1788
1789
        index, adapter = self.make_index(nodes=[
1789
 
            (('notprefix', 'key1'), 'data', ((), )),
1790
 
            (('prefix', 'key1'), 'data1', ((), )),
1791
 
            (('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'),),))])
1792
1793
        self.assertEqual(2, adapter.key_count())
1793
1794
 
1794
1795
    def test_validate(self):