/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: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Tests for indices."""
18
18
 
19
 
from ... import (
 
19
from .. import (
20
20
    errors,
21
21
    tests,
22
22
    transport,
23
23
    )
24
 
from .. import (
25
 
    index as _mod_index,
 
24
from ..bzr import (
 
25
    index,
26
26
    )
27
27
 
28
28
 
29
 
class ErrorTests(tests.TestCase):
30
 
 
31
 
    def test_bad_index_format_signature(self):
32
 
        error = _mod_index.BadIndexFormatSignature("foo", "bar")
33
 
        self.assertEqual("foo is not an index of type bar.",
34
 
                         str(error))
35
 
 
36
 
    def test_bad_index_data(self):
37
 
        error = _mod_index.BadIndexData("foo")
38
 
        self.assertEqual("Error in data for index foo.",
39
 
                         str(error))
40
 
 
41
 
    def test_bad_index_duplicate_key(self):
42
 
        error = _mod_index.BadIndexDuplicateKey("foo", "bar")
43
 
        self.assertEqual("The key 'foo' is already in index 'bar'.",
44
 
                         str(error))
45
 
 
46
 
    def test_bad_index_key(self):
47
 
        error = _mod_index.BadIndexKey("foo")
48
 
        self.assertEqual("The key 'foo' is not a valid key.",
49
 
                         str(error))
50
 
 
51
 
    def test_bad_index_options(self):
52
 
        error = _mod_index.BadIndexOptions("foo")
53
 
        self.assertEqual("Could not parse options for index foo.",
54
 
                         str(error))
55
 
 
56
 
    def test_bad_index_value(self):
57
 
        error = _mod_index.BadIndexValue("foo")
58
 
        self.assertEqual("The value 'foo' is not a valid value.",
59
 
                         str(error))
60
 
 
61
 
 
62
29
class TestGraphIndexBuilder(tests.TestCaseWithMemoryTransport):
63
30
 
64
31
    def test_build_index_empty(self):
65
 
        builder = _mod_index.GraphIndexBuilder()
 
32
        builder = index.GraphIndexBuilder()
66
33
        stream = builder.finish()
67
34
        contents = stream.read()
68
35
        self.assertEqual(
69
 
            b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=0\n\n",
 
36
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=0\n\n",
70
37
            contents)
71
38
 
72
39
    def test_build_index_empty_two_element_keys(self):
73
 
        builder = _mod_index.GraphIndexBuilder(key_elements=2)
 
40
        builder = index.GraphIndexBuilder(key_elements=2)
74
41
        stream = builder.finish()
75
42
        contents = stream.read()
76
43
        self.assertEqual(
77
 
            b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=0\n\n",
 
44
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=0\n\n",
78
45
            contents)
79
46
 
80
47
    def test_build_index_one_reference_list_empty(self):
81
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
 
48
        builder = index.GraphIndexBuilder(reference_lists=1)
82
49
        stream = builder.finish()
83
50
        contents = stream.read()
84
51
        self.assertEqual(
85
 
            b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=0\n\n",
 
52
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=0\n\n",
86
53
            contents)
87
54
 
88
55
    def test_build_index_two_reference_list_empty(self):
89
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
 
56
        builder = index.GraphIndexBuilder(reference_lists=2)
90
57
        stream = builder.finish()
91
58
        contents = stream.read()
92
59
        self.assertEqual(
93
 
            b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=0\n\n",
 
60
            "Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=0\n\n",
94
61
            contents)
95
62
 
96
63
    def test_build_index_one_node_no_refs(self):
97
 
        builder = _mod_index.GraphIndexBuilder()
98
 
        builder.add_node((b'akey', ), b'data')
 
64
        builder = index.GraphIndexBuilder()
 
65
        builder.add_node(('akey', ), 'data')
99
66
        stream = builder.finish()
100
67
        contents = stream.read()
101
68
        self.assertEqual(
102
 
            b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
103
 
            b"akey\x00\x00\x00data\n\n", contents)
 
69
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
 
70
            "akey\x00\x00\x00data\n\n", contents)
104
71
 
105
72
    def test_build_index_one_node_no_refs_accepts_empty_reflist(self):
106
 
        builder = _mod_index.GraphIndexBuilder()
107
 
        builder.add_node((b'akey', ), b'data', ())
 
73
        builder = index.GraphIndexBuilder()
 
74
        builder.add_node(('akey', ), 'data', ())
108
75
        stream = builder.finish()
109
76
        contents = stream.read()
110
77
        self.assertEqual(
111
 
            b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
112
 
            b"akey\x00\x00\x00data\n\n", contents)
 
78
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
 
79
            "akey\x00\x00\x00data\n\n", contents)
113
80
 
114
81
    def test_build_index_one_node_2_element_keys(self):
115
82
        # multipart keys are separated by \x00 - because they are fixed length,
116
83
        # not variable this does not cause any issues, and seems clearer to the
117
84
        # author.
118
 
        builder = _mod_index.GraphIndexBuilder(key_elements=2)
119
 
        builder.add_node((b'akey', b'secondpart'), b'data')
 
85
        builder = index.GraphIndexBuilder(key_elements=2)
 
86
        builder.add_node(('akey', 'secondpart'), 'data')
120
87
        stream = builder.finish()
121
88
        contents = stream.read()
122
89
        self.assertEqual(
123
 
            b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=1\n"
124
 
            b"akey\x00secondpart\x00\x00\x00data\n\n", contents)
 
90
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=1\n"
 
91
            "akey\x00secondpart\x00\x00\x00data\n\n", contents)
125
92
 
126
93
    def test_add_node_empty_value(self):
127
 
        builder = _mod_index.GraphIndexBuilder()
128
 
        builder.add_node((b'akey', ), b'')
 
94
        builder = index.GraphIndexBuilder()
 
95
        builder.add_node(('akey', ), '')
129
96
        stream = builder.finish()
130
97
        contents = stream.read()
131
98
        self.assertEqual(
132
 
            b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
133
 
            b"akey\x00\x00\x00\n\n", contents)
 
99
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
 
100
            "akey\x00\x00\x00\n\n", contents)
134
101
 
135
102
    def test_build_index_nodes_sorted(self):
136
103
        # the highest sorted node comes first.
137
 
        builder = _mod_index.GraphIndexBuilder()
 
104
        builder = index.GraphIndexBuilder()
138
105
        # use three to have a good chance of glitching dictionary hash
139
106
        # lookups etc. Insert in randomish order that is not correct
140
107
        # and not the reverse of the correct order.
141
 
        builder.add_node((b'2002', ), b'data')
142
 
        builder.add_node((b'2000', ), b'data')
143
 
        builder.add_node((b'2001', ), b'data')
 
108
        builder.add_node(('2002', ), 'data')
 
109
        builder.add_node(('2000', ), 'data')
 
110
        builder.add_node(('2001', ), 'data')
144
111
        stream = builder.finish()
145
112
        contents = stream.read()
146
113
        self.assertEqual(
147
 
            b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=3\n"
148
 
            b"2000\x00\x00\x00data\n"
149
 
            b"2001\x00\x00\x00data\n"
150
 
            b"2002\x00\x00\x00data\n"
151
 
            b"\n", contents)
 
114
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=3\n"
 
115
            "2000\x00\x00\x00data\n"
 
116
            "2001\x00\x00\x00data\n"
 
117
            "2002\x00\x00\x00data\n"
 
118
            "\n", contents)
152
119
 
153
120
    def test_build_index_2_element_key_nodes_sorted(self):
154
121
        # multiple element keys are sorted first-key, second-key.
155
 
        builder = _mod_index.GraphIndexBuilder(key_elements=2)
 
122
        builder = index.GraphIndexBuilder(key_elements=2)
156
123
        # use three values of each key element, to have a good chance of
157
124
        # glitching dictionary hash lookups etc. Insert in randomish order that
158
125
        # is not correct and not the reverse of the correct order.
159
 
        builder.add_node((b'2002', b'2002'), b'data')
160
 
        builder.add_node((b'2002', b'2000'), b'data')
161
 
        builder.add_node((b'2002', b'2001'), b'data')
162
 
        builder.add_node((b'2000', b'2002'), b'data')
163
 
        builder.add_node((b'2000', b'2000'), b'data')
164
 
        builder.add_node((b'2000', b'2001'), b'data')
165
 
        builder.add_node((b'2001', b'2002'), b'data')
166
 
        builder.add_node((b'2001', b'2000'), b'data')
167
 
        builder.add_node((b'2001', b'2001'), b'data')
 
126
        builder.add_node(('2002', '2002'), 'data')
 
127
        builder.add_node(('2002', '2000'), 'data')
 
128
        builder.add_node(('2002', '2001'), 'data')
 
129
        builder.add_node(('2000', '2002'), 'data')
 
130
        builder.add_node(('2000', '2000'), 'data')
 
131
        builder.add_node(('2000', '2001'), 'data')
 
132
        builder.add_node(('2001', '2002'), 'data')
 
133
        builder.add_node(('2001', '2000'), 'data')
 
134
        builder.add_node(('2001', '2001'), 'data')
168
135
        stream = builder.finish()
169
136
        contents = stream.read()
170
137
        self.assertEqual(
171
 
            b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=9\n"
172
 
            b"2000\x002000\x00\x00\x00data\n"
173
 
            b"2000\x002001\x00\x00\x00data\n"
174
 
            b"2000\x002002\x00\x00\x00data\n"
175
 
            b"2001\x002000\x00\x00\x00data\n"
176
 
            b"2001\x002001\x00\x00\x00data\n"
177
 
            b"2001\x002002\x00\x00\x00data\n"
178
 
            b"2002\x002000\x00\x00\x00data\n"
179
 
            b"2002\x002001\x00\x00\x00data\n"
180
 
            b"2002\x002002\x00\x00\x00data\n"
181
 
            b"\n", contents)
 
138
            "Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=9\n"
 
139
            "2000\x002000\x00\x00\x00data\n"
 
140
            "2000\x002001\x00\x00\x00data\n"
 
141
            "2000\x002002\x00\x00\x00data\n"
 
142
            "2001\x002000\x00\x00\x00data\n"
 
143
            "2001\x002001\x00\x00\x00data\n"
 
144
            "2001\x002002\x00\x00\x00data\n"
 
145
            "2002\x002000\x00\x00\x00data\n"
 
146
            "2002\x002001\x00\x00\x00data\n"
 
147
            "2002\x002002\x00\x00\x00data\n"
 
148
            "\n", contents)
182
149
 
183
150
    def test_build_index_reference_lists_are_included_one(self):
184
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
185
 
        builder.add_node((b'key', ), b'data', ([], ))
 
151
        builder = index.GraphIndexBuilder(reference_lists=1)
 
152
        builder.add_node(('key', ), 'data', ([], ))
186
153
        stream = builder.finish()
187
154
        contents = stream.read()
188
155
        self.assertEqual(
189
 
            b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
190
 
            b"key\x00\x00\x00data\n"
191
 
            b"\n", contents)
 
156
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
 
157
            "key\x00\x00\x00data\n"
 
158
            "\n", contents)
192
159
 
193
160
    def test_build_index_reference_lists_with_2_element_keys(self):
194
 
        builder = _mod_index.GraphIndexBuilder(
195
 
            reference_lists=1, key_elements=2)
196
 
        builder.add_node((b'key', b'key2'), b'data', ([], ))
 
161
        builder = index.GraphIndexBuilder(reference_lists=1, key_elements=2)
 
162
        builder.add_node(('key', 'key2'), 'data', ([], ))
197
163
        stream = builder.finish()
198
164
        contents = stream.read()
199
165
        self.assertEqual(
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)
 
166
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\nlen=1\n"
 
167
            "key\x00key2\x00\x00\x00data\n"
 
168
            "\n", contents)
203
169
 
204
170
    def test_build_index_reference_lists_are_included_two(self):
205
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
206
 
        builder.add_node((b'key', ), b'data', ([], []))
 
171
        builder = index.GraphIndexBuilder(reference_lists=2)
 
172
        builder.add_node(('key', ), 'data', ([], []))
207
173
        stream = builder.finish()
208
174
        contents = stream.read()
209
175
        self.assertEqual(
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)
 
176
            "Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
 
177
            "key\x00\x00\t\x00data\n"
 
178
            "\n", contents)
213
179
 
214
180
    def test_clear_cache(self):
215
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
 
181
        builder = index.GraphIndexBuilder(reference_lists=2)
216
182
        # This is a no-op, but the api should exist
217
183
        builder.clear_cache()
218
184
 
219
185
    def test_node_references_are_byte_offsets(self):
220
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
221
 
        builder.add_node((b'reference', ), b'data', ([], ))
222
 
        builder.add_node((b'key', ), b'data', ([(b'reference', )], ))
 
186
        builder = index.GraphIndexBuilder(reference_lists=1)
 
187
        builder.add_node(('reference', ), 'data', ([], ))
 
188
        builder.add_node(('key', ), 'data', ([('reference', )], ))
223
189
        stream = builder.finish()
224
190
        contents = stream.read()
225
191
        self.assertEqual(
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)
 
192
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=2\n"
 
193
            "key\x00\x0072\x00data\n"
 
194
            "reference\x00\x00\x00data\n"
 
195
            "\n", contents)
230
196
 
231
197
    def test_node_references_are_cr_delimited(self):
232
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
233
 
        builder.add_node((b'reference', ), b'data', ([], ))
234
 
        builder.add_node((b'reference2', ), b'data', ([], ))
235
 
        builder.add_node((b'key', ), b'data',
236
 
                         ([(b'reference', ), (b'reference2', )], ))
 
198
        builder = index.GraphIndexBuilder(reference_lists=1)
 
199
        builder.add_node(('reference', ), 'data', ([], ))
 
200
        builder.add_node(('reference2', ), 'data', ([], ))
 
201
        builder.add_node(('key', ), 'data',
 
202
                         ([('reference', ), ('reference2', )], ))
237
203
        stream = builder.finish()
238
204
        contents = stream.read()
239
205
        self.assertEqual(
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)
 
206
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=3\n"
 
207
            "key\x00\x00077\r094\x00data\n"
 
208
            "reference\x00\x00\x00data\n"
 
209
            "reference2\x00\x00\x00data\n"
 
210
            "\n", contents)
245
211
 
246
212
    def test_multiple_reference_lists_are_tab_delimited(self):
247
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
248
 
        builder.add_node((b'keference', ), b'data', ([], []))
249
 
        builder.add_node((b'rey', ), b'data',
250
 
                         ([(b'keference', )], [(b'keference', )]))
 
213
        builder = index.GraphIndexBuilder(reference_lists=2)
 
214
        builder.add_node(('keference', ), 'data', ([], []))
 
215
        builder.add_node(('rey', ), 'data',
 
216
                         ([('keference', )], [('keference', )]))
251
217
        stream = builder.finish()
252
218
        contents = stream.read()
253
219
        self.assertEqual(
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)
 
220
            "Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=2\n"
 
221
            "keference\x00\x00\t\x00data\n"
 
222
            "rey\x00\x0059\t59\x00data\n"
 
223
            "\n", contents)
258
224
 
259
225
    def test_add_node_referencing_missing_key_makes_absent(self):
260
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
261
 
        builder.add_node((b'rey', ), b'data',
262
 
                         ([(b'beference', ), (b'aeference2', )], ))
 
226
        builder = index.GraphIndexBuilder(reference_lists=1)
 
227
        builder.add_node(('rey', ), 'data',
 
228
                         ([('beference', ), ('aeference2', )], ))
263
229
        stream = builder.finish()
264
230
        contents = stream.read()
265
231
        self.assertEqual(
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)
 
232
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
 
233
            "aeference2\x00a\x00\x00\n"
 
234
            "beference\x00a\x00\x00\n"
 
235
            "rey\x00\x00074\r059\x00data\n"
 
236
            "\n", contents)
271
237
 
272
238
    def test_node_references_three_digits(self):
273
239
        # test the node digit expands as needed.
274
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
275
 
        references = [((b"%d" % val), ) for val in range(8, -1, -1)]
276
 
        builder.add_node((b'2-key', ), b'', (references, ))
 
240
        builder = index.GraphIndexBuilder(reference_lists=1)
 
241
        references = [(str(val), ) for val in range(8, -1, -1)]
 
242
        builder.add_node(('2-key', ), '', (references, ))
277
243
        stream = builder.finish()
278
244
        contents = stream.read()
279
245
        self.assertEqualDiff(
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)
 
246
            "Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
 
247
            "0\x00a\x00\x00\n"
 
248
            "1\x00a\x00\x00\n"
 
249
            "2\x00a\x00\x00\n"
 
250
            "2-key\x00\x00151\r145\r139\r133\r127\r121\r071\r065\r059\x00\n"
 
251
            "3\x00a\x00\x00\n"
 
252
            "4\x00a\x00\x00\n"
 
253
            "5\x00a\x00\x00\n"
 
254
            "6\x00a\x00\x00\n"
 
255
            "7\x00a\x00\x00\n"
 
256
            "8\x00a\x00\x00\n"
 
257
            "\n", contents)
292
258
 
293
259
    def test_absent_has_no_reference_overhead(self):
294
260
        # the offsets after an absent record should be correct when there are
295
261
        # >1 reference lists.
296
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
297
 
        builder.add_node((b'parent', ), b'', ([(b'aail', ), (b'zther', )], []))
 
262
        builder = index.GraphIndexBuilder(reference_lists=2)
 
263
        builder.add_node(('parent', ), '', ([('aail', ), ('zther', )], []))
298
264
        stream = builder.finish()
299
265
        contents = stream.read()
300
266
        self.assertEqual(
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)
 
267
            "Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
 
268
            "aail\x00a\x00\x00\n"
 
269
            "parent\x00\x0059\r84\t\x00\n"
 
270
            "zther\x00a\x00\x00\n"
 
271
            "\n", contents)
306
272
 
307
273
    def test_add_node_bad_key(self):
308
 
        builder = _mod_index.GraphIndexBuilder()
309
 
        for bad_char in bytearray(b'\t\n\x0b\x0c\r\x00 '):
310
 
            self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
311
 
                              (b'a%skey' % bytes([bad_char]), ), b'data')
312
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
313
 
                          (), b'data')
314
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
315
 
                          b'not-a-tuple', b'data')
 
274
        builder = index.GraphIndexBuilder()
 
275
        for bad_char in '\t\n\x0b\x0c\r\x00 ':
 
276
            self.assertRaises(errors.BadIndexKey, builder.add_node,
 
277
                ('a%skey' % bad_char, ), 'data')
 
278
        self.assertRaises(errors.BadIndexKey, builder.add_node,
 
279
                ('', ), 'data')
 
280
        self.assertRaises(errors.BadIndexKey, builder.add_node,
 
281
                'not-a-tuple', 'data')
316
282
        # not enough length
317
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
318
 
                          (), b'data')
 
283
        self.assertRaises(errors.BadIndexKey, builder.add_node,
 
284
                (), 'data')
319
285
        # too long
320
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
321
 
                          (b'primary', b'secondary'), b'data')
 
286
        self.assertRaises(errors.BadIndexKey, builder.add_node,
 
287
                ('primary', 'secondary'), 'data')
322
288
        # secondary key elements get checked too:
323
 
        builder = _mod_index.GraphIndexBuilder(key_elements=2)
324
 
        for bad_char in bytearray(b'\t\n\x0b\x0c\r\x00 '):
325
 
            self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
326
 
                              (b'prefix', b'a%skey' % bytes([bad_char])), b'data')
 
289
        builder = index.GraphIndexBuilder(key_elements=2)
 
290
        for bad_char in '\t\n\x0b\x0c\r\x00 ':
 
291
            self.assertRaises(errors.BadIndexKey, builder.add_node,
 
292
                ('prefix', 'a%skey' % bad_char), 'data')
327
293
 
328
294
    def test_add_node_bad_data(self):
329
 
        builder = _mod_index.GraphIndexBuilder()
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')
 
295
        builder = index.GraphIndexBuilder()
 
296
        self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
 
297
            'data\naa')
 
298
        self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
 
299
            'data\x00aa')
334
300
 
335
301
    def test_add_node_bad_mismatched_ref_lists_length(self):
336
 
        builder = _mod_index.GraphIndexBuilder()
337
 
        self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
338
 
                          b'data aa', ([], ))
339
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
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', ([], []))
346
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
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', ([], [], []))
 
302
        builder = index.GraphIndexBuilder()
 
303
        self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
 
304
            'data aa', ([], ))
 
305
        builder = index.GraphIndexBuilder(reference_lists=1)
 
306
        self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
 
307
            'data aa')
 
308
        self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
 
309
            'data aa', (), )
 
310
        self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
 
311
            'data aa', ([], []))
 
312
        builder = index.GraphIndexBuilder(reference_lists=2)
 
313
        self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
 
314
            'data aa')
 
315
        self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
 
316
            'data aa', ([], ))
 
317
        self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
 
318
            'data aa', ([], [], []))
353
319
 
354
320
    def test_add_node_bad_key_in_reference_lists(self):
355
321
        # first list, first key - trivial
356
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
357
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
358
 
                          b'data aa', ([(b'a key', )], ))
 
322
        builder = index.GraphIndexBuilder(reference_lists=1)
 
323
        self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
 
324
            'data aa', ([('a key', )], ))
359
325
        # references keys must be tuples too
360
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
361
 
                          b'data aa', (['not-a-tuple'], ))
 
326
        self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
 
327
            'data aa', (['not-a-tuple'], ))
362
328
        # not enough length
363
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
364
 
                          b'data aa', ([()], ))
 
329
        self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
 
330
            'data aa', ([()], ))
365
331
        # too long
366
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
367
 
                          b'data aa', ([(b'primary', b'secondary')], ))
 
332
        self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
 
333
            'data aa', ([('primary', 'secondary')], ))
368
334
        # need to check more than the first key in the list
369
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
370
 
                          b'data aa', ([(b'agoodkey', ), (b'that is a bad key', )], ))
 
335
        self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
 
336
            'data aa', ([('agoodkey', ), ('that is a bad key', )], ))
371
337
        # and if there is more than one list it should be getting checked
372
338
        # too
373
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=2)
374
 
        self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
375
 
                          b'data aa', ([], ['a bad key']))
 
339
        builder = index.GraphIndexBuilder(reference_lists=2)
 
340
        self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
 
341
            'data aa', ([], ['a bad key']))
376
342
 
377
343
    def test_add_duplicate_key(self):
378
 
        builder = _mod_index.GraphIndexBuilder()
379
 
        builder.add_node((b'key', ), b'data')
380
 
        self.assertRaises(_mod_index.BadIndexDuplicateKey,
381
 
                          builder.add_node, (b'key', ), b'data')
 
344
        builder = index.GraphIndexBuilder()
 
345
        builder.add_node(('key', ), 'data')
 
346
        self.assertRaises(errors.BadIndexDuplicateKey,
 
347
                          builder.add_node, ('key', ), 'data')
382
348
 
383
349
    def test_add_duplicate_key_2_elements(self):
384
 
        builder = _mod_index.GraphIndexBuilder(key_elements=2)
385
 
        builder.add_node((b'key', b'key'), b'data')
386
 
        self.assertRaises(_mod_index.BadIndexDuplicateKey, builder.add_node,
387
 
                          (b'key', b'key'), b'data')
 
350
        builder = index.GraphIndexBuilder(key_elements=2)
 
351
        builder.add_node(('key', 'key'), 'data')
 
352
        self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node,
 
353
            ('key', 'key'), 'data')
388
354
 
389
355
    def test_add_key_after_referencing_key(self):
390
 
        builder = _mod_index.GraphIndexBuilder(reference_lists=1)
391
 
        builder.add_node((b'key', ), b'data', ([(b'reference', )], ))
392
 
        builder.add_node((b'reference', ), b'data', ([],))
 
356
        builder = index.GraphIndexBuilder(reference_lists=1)
 
357
        builder.add_node(('key', ), 'data', ([('reference', )], ))
 
358
        builder.add_node(('reference', ), 'data', ([],))
393
359
 
394
360
    def test_add_key_after_referencing_key_2_elements(self):
395
 
        builder = _mod_index.GraphIndexBuilder(
396
 
            reference_lists=1, key_elements=2)
397
 
        builder.add_node((b'k', b'ey'), b'data',
398
 
                         ([(b'reference', b'tokey')], ))
399
 
        builder.add_node((b'reference', b'tokey'), b'data', ([],))
 
361
        builder = index.GraphIndexBuilder(reference_lists=1, key_elements=2)
 
362
        builder.add_node(('k', 'ey'), 'data', ([('reference', 'tokey')], ))
 
363
        builder.add_node(('reference', 'tokey'), 'data', ([],))
400
364
 
401
365
    def test_set_optimize(self):
402
 
        builder = _mod_index.GraphIndexBuilder(
403
 
            reference_lists=1, key_elements=2)
 
366
        builder = index.GraphIndexBuilder(reference_lists=1, key_elements=2)
404
367
        builder.set_optimize(for_size=True)
405
368
        self.assertTrue(builder._optimize_for_size)
406
369
        builder.set_optimize(for_size=False)
410
373
class TestGraphIndex(tests.TestCaseWithMemoryTransport):
411
374
 
412
375
    def make_key(self, number):
413
 
        return ((b'%d' % number) + b'X' * 100,)
 
376
        return (str(number) + 'X'*100,)
414
377
 
415
378
    def make_value(self, number):
416
 
        return (b'%d' % number) + b'Y' * 100
 
379
            return str(number) + 'Y'*100
417
380
 
418
381
    def make_nodes(self, count=64):
419
382
        # generate a big enough index that we only read some of it on a typical
420
383
        # bisection lookup.
421
384
        nodes = []
422
385
        for counter in range(count):
423
 
            nodes.append(
424
 
                (self.make_key(counter), self.make_value(counter), ()))
 
386
            nodes.append((self.make_key(counter), self.make_value(counter), ()))
425
387
        return nodes
426
388
 
427
389
    def make_index(self, ref_lists=0, key_elements=1, nodes=[]):
428
 
        builder = _mod_index.GraphIndexBuilder(
429
 
            ref_lists, key_elements=key_elements)
 
390
        builder = index.GraphIndexBuilder(ref_lists, key_elements=key_elements)
430
391
        for key, value, references in nodes:
431
392
            builder.add_node(key, value, references)
432
393
        stream = builder.finish()
433
394
        trans = transport.get_transport_from_url('trace+' + self.get_url())
434
395
        size = trans.put_file('index', stream)
435
 
        return _mod_index.GraphIndex(trans, 'index', size)
 
396
        return index.GraphIndex(trans, 'index', size)
436
397
 
437
398
    def make_index_with_offset(self, ref_lists=0, key_elements=1, nodes=[],
438
399
                               offset=0):
439
 
        builder = _mod_index.GraphIndexBuilder(
440
 
            ref_lists, key_elements=key_elements)
 
400
        builder = index.GraphIndexBuilder(ref_lists, key_elements=key_elements)
441
401
        for key, value, references in nodes:
442
402
            builder.add_node(key, value, references)
443
403
        content = builder.finish().read()
444
404
        size = len(content)
445
405
        trans = self.get_transport()
446
 
        trans.put_bytes('index', (b' ' * offset) + content)
447
 
        return _mod_index.GraphIndex(trans, 'index', size, offset=offset)
 
406
        trans.put_bytes('index', (' '*offset) + content)
 
407
        return index.GraphIndex(trans, 'index', size, offset=offset)
448
408
 
449
409
    def test_clear_cache(self):
450
410
        index = self.make_index()
454
414
 
455
415
    def test_open_bad_index_no_error(self):
456
416
        trans = self.get_transport()
457
 
        trans.put_bytes('name', b"not an index\n")
458
 
        idx = _mod_index.GraphIndex(trans, 'name', 13)
 
417
        trans.put_bytes('name', "not an index\n")
 
418
        idx = index.GraphIndex(trans, 'name', 13)
459
419
 
460
420
    def test_with_offset(self):
461
421
        nodes = self.make_nodes(200)
471
431
    def test_side_effect_buffering_with_offset(self):
472
432
        nodes = self.make_nodes(20)
473
433
        index = self.make_index_with_offset(offset=1234567, nodes=nodes)
474
 
        index._transport.recommended_page_size = lambda: 64 * 1024
 
434
        index._transport.recommended_page_size = lambda:64*1024
475
435
        subset_nodes = [nodes[0][0], nodes[10][0], nodes[19][0]]
476
436
        entries = [n[1] for n in index.iter_entries(subset_nodes)]
477
437
        self.assertEqual(sorted(subset_nodes), sorted(entries))
503
463
        # do a _lookup_keys_via_location call for the middle of the file, which
504
464
        # is what bisection uses.
505
465
        result = index._lookup_keys_via_location(
506
 
            [(index._size // 2, (b'missing', ))])
 
466
            [(index._size // 2, ('missing', ))])
507
467
        # this should have asked for a readv request, with adjust_for_latency,
508
468
        # and two regions: the header, and half-way into the file.
509
469
        self.assertEqual([
512
472
            index._transport._activity)
513
473
        # and the result should be that the key cannot be present, because this
514
474
        # is a trivial index.
515
 
        self.assertEqual([((index._size // 2, (b'missing', )), False)],
516
 
                         result)
 
475
        self.assertEqual([((index._size // 2, ('missing', )), False)],
 
476
            result)
517
477
        # And this should have caused the file to be fully buffered
518
478
        self.assertIsNot(None, index._nodes)
519
479
        self.assertEqual([], index._parsed_byte_map)
533
493
        # is what bisection uses.
534
494
        start_lookup = index._size // 2
535
495
        result = index._lookup_keys_via_location(
536
 
            [(start_lookup, (b'40missing', ))])
 
496
            [(start_lookup, ('40missing', ))])
537
497
        # this should have asked for a readv request, with adjust_for_latency,
538
498
        # and two regions: the header, and half-way into the file.
539
499
        self.assertEqual([
543
503
            index._transport._activity)
544
504
        # and the result should be that the key cannot be present, because this
545
505
        # is a trivial index.
546
 
        self.assertEqual([((start_lookup, (b'40missing', )), False)],
547
 
                         result)
 
506
        self.assertEqual([((start_lookup, ('40missing', )), False)],
 
507
            result)
548
508
        # And this should not have caused the file to be fully buffered
549
509
        self.assertIs(None, index._nodes)
550
510
        # And the regions of the file that have been parsed should be in the
551
511
        # parsed_byte_map and the parsed_key_map
552
512
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
553
 
        self.assertEqual([((), self.make_key(26)),
 
513
        self.assertEqual([(None, self.make_key(26)),
554
514
                          (self.make_key(31), self.make_key(48))],
555
515
                         index._parsed_key_map)
556
516
 
557
517
    def test_parsing_non_adjacent_data_trims(self):
558
518
        index = self.make_index(nodes=self.make_nodes(64))
559
519
        result = index._lookup_keys_via_location(
560
 
            [(index._size // 2, (b'40', ))])
 
520
            [(index._size // 2, ('40', ))])
561
521
        # and the result should be that the key cannot be present, because key is
562
522
        # in the middle of the observed data from a 4K read - the smallest transport
563
523
        # will do today with this api.
564
 
        self.assertEqual([((index._size // 2, (b'40', )), False)],
565
 
                         result)
 
524
        self.assertEqual([((index._size // 2, ('40', )), False)],
 
525
            result)
566
526
        # and we should have a parse map that includes the header and the
567
527
        # region that was parsed after trimming.
568
528
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
569
 
        self.assertEqual([((), self.make_key(26)),
 
529
        self.assertEqual([(None, self.make_key(26)),
570
530
                          (self.make_key(31), self.make_key(48))],
571
 
                         index._parsed_key_map)
 
531
            index._parsed_key_map)
572
532
 
573
533
    def test_parsing_data_handles_parsed_contained_regions(self):
574
534
        # the following patten creates a parsed region that is wholly within a
586
546
        # locations of both keys.
587
547
        index = self.make_index(nodes=self.make_nodes(128))
588
548
        result = index._lookup_keys_via_location(
589
 
            [(index._size // 2, (b'40', ))])
 
549
            [(index._size // 2, ('40', ))])
590
550
        # and we should have a parse map that includes the header and the
591
551
        # region that was parsed after trimming.
592
552
        self.assertEqual([(0, 4045), (11759, 15707)], index._parsed_byte_map)
593
 
        self.assertEqual([((), self.make_key(116)),
 
553
        self.assertEqual([(None, self.make_key(116)),
594
554
                          (self.make_key(35), self.make_key(51))],
595
 
                         index._parsed_key_map)
 
555
            index._parsed_key_map)
596
556
        # now ask for two keys, right before and after the parsed region
597
557
        result = index._lookup_keys_via_location(
598
558
            [(11450, self.make_key(34)), (15707, self.make_key(52))])
610
570
        # bisection lookup.
611
571
        index = self.make_index(nodes=self.make_nodes(64))
612
572
        # lookup the keys in the middle of the file
613
 
        result = index._lookup_keys_via_location(
614
 
            [(index._size // 2, (b'40', ))])
 
573
        result =index._lookup_keys_via_location(
 
574
            [(index._size // 2, ('40', ))])
615
575
        # check the parse map, this determines the test validity
616
576
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
617
 
        self.assertEqual([((), self.make_key(26)),
 
577
        self.assertEqual([(None, self.make_key(26)),
618
578
                          (self.make_key(31), self.make_key(48))],
619
 
                         index._parsed_key_map)
 
579
            index._parsed_key_map)
620
580
        # reset the transport log
621
581
        del index._transport._activity[:]
622
582
        # now looking up a key in the portion of the file already parsed should
624
584
        # be in the index) - even when the byte location we ask for is outside
625
585
        # the parsed region
626
586
        result = index._lookup_keys_via_location(
627
 
            [(4000, (b'40', ))])
628
 
        self.assertEqual([((4000, (b'40', )), False)],
629
 
                         result)
 
587
            [(4000, ('40', ))])
 
588
        self.assertEqual([((4000, ('40', )), False)],
 
589
            result)
630
590
        self.assertEqual([], index._transport._activity)
631
591
 
632
592
    def test_lookup_present_key_answers_without_io_when_map_permits(self):
634
594
        # bisection lookup.
635
595
        index = self.make_index(nodes=self.make_nodes(64))
636
596
        # lookup the keys in the middle of the file
637
 
        result = index._lookup_keys_via_location(
638
 
            [(index._size // 2, (b'40', ))])
 
597
        result =index._lookup_keys_via_location(
 
598
            [(index._size // 2, ('40', ))])
639
599
        # check the parse map, this determines the test validity
640
600
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
641
 
        self.assertEqual([((), self.make_key(26)),
 
601
        self.assertEqual([(None, self.make_key(26)),
642
602
                          (self.make_key(31), self.make_key(48))],
643
 
                         index._parsed_key_map)
 
603
            index._parsed_key_map)
644
604
        # reset the transport log
645
605
        del index._transport._activity[:]
646
606
        # now looking up a key in the portion of the file already parsed should
661
621
        index = self.make_index(nodes=self.make_nodes(64))
662
622
        # ask for the key in the middle, but a key that is located in the
663
623
        # unparsed region before the middle.
664
 
        result = index._lookup_keys_via_location(
665
 
            [(index._size // 2, (b'30', ))])
 
624
        result =index._lookup_keys_via_location(
 
625
            [(index._size // 2, ('30', ))])
666
626
        # check the parse map, this determines the test validity
667
627
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
668
 
        self.assertEqual([((), self.make_key(26)),
 
628
        self.assertEqual([(None, self.make_key(26)),
669
629
                          (self.make_key(31), self.make_key(48))],
670
 
                         index._parsed_key_map)
671
 
        self.assertEqual([((index._size // 2, (b'30', )), -1)],
672
 
                         result)
 
630
            index._parsed_key_map)
 
631
        self.assertEqual([((index._size // 2, ('30', )), -1)],
 
632
            result)
673
633
 
674
634
    def test_lookup_key_above_probed_area(self):
675
635
        # generate a big enough index that we only read some of it on a typical
677
637
        index = self.make_index(nodes=self.make_nodes(64))
678
638
        # ask for the key in the middle, but a key that is located in the
679
639
        # unparsed region after the middle.
680
 
        result = index._lookup_keys_via_location(
681
 
            [(index._size // 2, (b'50', ))])
 
640
        result =index._lookup_keys_via_location(
 
641
            [(index._size // 2, ('50', ))])
682
642
        # check the parse map, this determines the test validity
683
643
        self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)
684
 
        self.assertEqual([((), self.make_key(26)),
 
644
        self.assertEqual([(None, self.make_key(26)),
685
645
                          (self.make_key(31), self.make_key(48))],
686
 
                         index._parsed_key_map)
687
 
        self.assertEqual([((index._size // 2, (b'50', )), +1)],
688
 
                         result)
 
646
            index._parsed_key_map)
 
647
        self.assertEqual([((index._size // 2, ('50', )), +1)],
 
648
            result)
689
649
 
690
650
    def test_lookup_key_resolves_references(self):
691
651
        # generate a big enough index that we only read some of it on a typical
693
653
        nodes = []
694
654
        for counter in range(99):
695
655
            nodes.append((self.make_key(counter), self.make_value(counter),
696
 
                          ((self.make_key(counter + 20),),)))
 
656
                ((self.make_key(counter + 20),),)  ))
697
657
        index = self.make_index(ref_lists=1, nodes=nodes)
698
658
        # lookup a key in the middle that does not exist, so that when we can
699
659
        # check that the referred-to-keys are not accessed automatically.
700
660
        index_size = index._size
701
661
        index_center = index_size // 2
702
662
        result = index._lookup_keys_via_location(
703
 
            [(index_center, (b'40', ))])
 
663
            [(index_center, ('40', ))])
704
664
        # check the parse map - only the start and middle should have been
705
665
        # parsed.
706
666
        self.assertEqual([(0, 4027), (10198, 14028)], index._parsed_byte_map)
707
 
        self.assertEqual([((), self.make_key(17)),
 
667
        self.assertEqual([(None, self.make_key(17)),
708
668
                          (self.make_key(44), self.make_key(5))],
709
 
                         index._parsed_key_map)
 
669
            index._parsed_key_map)
710
670
        # and check the transport activity likewise.
711
671
        self.assertEqual(
712
672
            [('readv', 'index', [(index_center, 800), (0, 200)], True,
713
 
              index_size)],
 
673
                                  index_size)],
714
674
            index._transport._activity)
715
675
        # reset the transport log for testing the reference lookup
716
676
        del index._transport._activity[:]
723
683
               ((self.make_key(65),),)))],
724
684
            result)
725
685
        self.assertEqual([('readv', 'index', [(15093, 800)], True, index_size)],
726
 
                         index._transport._activity)
 
686
            index._transport._activity)
727
687
 
728
688
    def test_lookup_key_can_buffer_all(self):
729
689
        nodes = []
730
690
        for counter in range(64):
731
691
            nodes.append((self.make_key(counter), self.make_value(counter),
732
 
                          ((self.make_key(counter + 20),),)))
 
692
                ((self.make_key(counter + 20),),)  ))
733
693
        index = self.make_index(ref_lists=1, nodes=nodes)
734
694
        # lookup a key in the middle that does not exist, so that when we can
735
695
        # check that the referred-to-keys are not accessed automatically.
736
696
        index_size = index._size
737
697
        index_center = index_size // 2
738
 
        result = index._lookup_keys_via_location([(index_center, (b'40', ))])
 
698
        result = index._lookup_keys_via_location([(index_center, ('40', ))])
739
699
        # check the parse map - only the start and middle should have been
740
700
        # parsed.
741
701
        self.assertEqual([(0, 3890), (6444, 10274)], index._parsed_byte_map)
742
 
        self.assertEqual([((), self.make_key(25)),
 
702
        self.assertEqual([(None, self.make_key(25)),
743
703
                          (self.make_key(37), self.make_key(52))],
744
 
                         index._parsed_key_map)
 
704
            index._parsed_key_map)
745
705
        # and check the transport activity likewise.
746
706
        self.assertEqual(
747
707
            [('readv', 'index', [(index_center, 800), (0, 200)], True,
748
 
              index_size)],
 
708
                                  index_size)],
749
709
            index._transport._activity)
750
710
        # reset the transport log for testing the reference lookup
751
711
        del index._transport._activity[:]
766
726
        self.assertEqual([], list(index.iter_all_entries()))
767
727
 
768
728
    def test_iter_all_entries_simple(self):
769
 
        index = self.make_index(nodes=[((b'name', ), b'data', ())])
770
 
        self.assertEqual([(index, (b'name', ), b'data')],
771
 
                         list(index.iter_all_entries()))
 
729
        index = self.make_index(nodes=[(('name', ), 'data', ())])
 
730
        self.assertEqual([(index, ('name', ), 'data')],
 
731
            list(index.iter_all_entries()))
772
732
 
773
733
    def test_iter_all_entries_simple_2_elements(self):
774
734
        index = self.make_index(key_elements=2,
775
 
                                nodes=[((b'name', b'surname'), b'data', ())])
776
 
        self.assertEqual([(index, (b'name', b'surname'), b'data')],
777
 
                         list(index.iter_all_entries()))
 
735
            nodes=[(('name', 'surname'), 'data', ())])
 
736
        self.assertEqual([(index, ('name', 'surname'), 'data')],
 
737
            list(index.iter_all_entries()))
778
738
 
779
739
    def test_iter_all_entries_references_resolved(self):
780
740
        index = self.make_index(1, nodes=[
781
 
            ((b'name', ), b'data', ([(b'ref', )], )),
782
 
            ((b'ref', ), b'refdata', ([], ))])
783
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
784
 
                          (index, (b'ref', ), b'refdata', ((), ))},
785
 
                         set(index.iter_all_entries()))
 
741
            (('name', ), 'data', ([('ref', )], )),
 
742
            (('ref', ), 'refdata', ([], ))])
 
743
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
 
744
            (index, ('ref', ), 'refdata', ((), ))},
 
745
            set(index.iter_all_entries()))
786
746
 
787
747
    def test_iter_entries_buffers_once(self):
788
748
        index = self.make_index(nodes=self.make_nodes(2))
828
788
 
829
789
    def test_iter_entries_references_resolved(self):
830
790
        index = self.make_index(1, nodes=[
831
 
            ((b'name', ), b'data', ([(b'ref', ), (b'ref', )], )),
832
 
            ((b'ref', ), b'refdata', ([], ))])
833
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',), (b'ref',)),)),
834
 
                          (index, (b'ref', ), b'refdata', ((), ))},
835
 
                         set(index.iter_entries([(b'name',), (b'ref',)])))
 
791
            (('name', ), 'data', ([('ref', ), ('ref', )], )),
 
792
            (('ref', ), 'refdata', ([], ))])
 
793
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),('ref',)),)),
 
794
            (index, ('ref', ), 'refdata', ((), ))},
 
795
            set(index.iter_entries([('name',), ('ref',)])))
836
796
 
837
797
    def test_iter_entries_references_2_refs_resolved(self):
838
798
        index = self.make_index(2, nodes=[
839
 
            ((b'name', ), b'data', ([(b'ref', )], [(b'ref', )])),
840
 
            ((b'ref', ), b'refdata', ([], []))])
841
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),), ((b'ref',),))),
842
 
                          (index, (b'ref', ), b'refdata', ((), ()))},
843
 
                         set(index.iter_entries([(b'name',), (b'ref',)])))
 
799
            (('name', ), 'data', ([('ref', )], [('ref', )])),
 
800
            (('ref', ), 'refdata', ([], []))])
 
801
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),), (('ref',),))),
 
802
            (index, ('ref', ), 'refdata', ((), ()))},
 
803
            set(index.iter_entries([('name',), ('ref',)])))
844
804
 
845
805
    def test_iteration_absent_skipped(self):
846
806
        index = self.make_index(1, nodes=[
847
 
            ((b'name', ), b'data', ([(b'ref', )], ))])
848
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
849
 
                         set(index.iter_all_entries()))
850
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
851
 
                         set(index.iter_entries([(b'name', )])))
852
 
        self.assertEqual([], list(index.iter_entries([(b'ref', )])))
 
807
            (('name', ), 'data', ([('ref', )], ))])
 
808
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),))},
 
809
            set(index.iter_all_entries()))
 
810
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),))},
 
811
            set(index.iter_entries([('name', )])))
 
812
        self.assertEqual([], list(index.iter_entries([('ref', )])))
853
813
 
854
814
    def test_iteration_absent_skipped_2_element_keys(self):
855
815
        index = self.make_index(1, key_elements=2, nodes=[
856
 
            ((b'name', b'fin'), b'data', ([(b'ref', b'erence')], ))])
857
 
        self.assertEqual([(index, (b'name', b'fin'), b'data', (((b'ref', b'erence'),),))],
858
 
                         list(index.iter_all_entries()))
859
 
        self.assertEqual([(index, (b'name', b'fin'), b'data', (((b'ref', b'erence'),),))],
860
 
                         list(index.iter_entries([(b'name', b'fin')])))
861
 
        self.assertEqual([], list(index.iter_entries([(b'ref', b'erence')])))
 
816
            (('name', 'fin'), 'data', ([('ref', 'erence')], ))])
 
817
        self.assertEqual({(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))},
 
818
            set(index.iter_all_entries()))
 
819
        self.assertEqual({(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))},
 
820
            set(index.iter_entries([('name', 'fin')])))
 
821
        self.assertEqual([], list(index.iter_entries([('ref', 'erence')])))
862
822
 
863
823
    def test_iter_all_keys(self):
864
824
        index = self.make_index(1, nodes=[
865
 
            ((b'name', ), b'data', ([(b'ref', )], )),
866
 
            ((b'ref', ), b'refdata', ([], ))])
867
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
868
 
                          (index, (b'ref', ), b'refdata', ((), ))},
869
 
                         set(index.iter_entries([(b'name', ), (b'ref', )])))
 
825
            (('name', ), 'data', ([('ref', )], )),
 
826
            (('ref', ), 'refdata', ([], ))])
 
827
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
 
828
            (index, ('ref', ), 'refdata', ((), ))},
 
829
            set(index.iter_entries([('name', ), ('ref', )])))
870
830
 
871
831
    def test_iter_nothing_empty(self):
872
832
        index = self.make_index()
874
834
 
875
835
    def test_iter_missing_entry_empty(self):
876
836
        index = self.make_index()
877
 
        self.assertEqual([], list(index.iter_entries([(b'a', )])))
 
837
        self.assertEqual([], list(index.iter_entries([('a', )])))
878
838
 
879
839
    def test_iter_missing_entry_empty_no_size(self):
880
840
        idx = self.make_index()
881
 
        idx = _mod_index.GraphIndex(idx._transport, 'index', None)
882
 
        self.assertEqual([], list(idx.iter_entries([(b'a', )])))
 
841
        idx = index.GraphIndex(idx._transport, 'index', None)
 
842
        self.assertEqual([], list(idx.iter_entries([('a', )])))
883
843
 
884
844
    def test_iter_key_prefix_1_element_key_None(self):
885
845
        index = self.make_index()
886
 
        self.assertRaises(_mod_index.BadIndexKey, list,
887
 
                          index.iter_entries_prefix([(None, )]))
 
846
        self.assertRaises(errors.BadIndexKey, list,
 
847
            index.iter_entries_prefix([(None, )]))
888
848
 
889
849
    def test_iter_key_prefix_wrong_length(self):
890
850
        index = self.make_index()
891
 
        self.assertRaises(_mod_index.BadIndexKey, list,
892
 
                          index.iter_entries_prefix([(b'foo', None)]))
 
851
        self.assertRaises(errors.BadIndexKey, list,
 
852
            index.iter_entries_prefix([('foo', None)]))
893
853
        index = self.make_index(key_elements=2)
894
 
        self.assertRaises(_mod_index.BadIndexKey, list,
895
 
                          index.iter_entries_prefix([(b'foo', )]))
896
 
        self.assertRaises(_mod_index.BadIndexKey, list,
897
 
                          index.iter_entries_prefix([(b'foo', None, None)]))
 
854
        self.assertRaises(errors.BadIndexKey, list,
 
855
            index.iter_entries_prefix([('foo', )]))
 
856
        self.assertRaises(errors.BadIndexKey, list,
 
857
            index.iter_entries_prefix([('foo', None, None)]))
898
858
 
899
859
    def test_iter_key_prefix_1_key_element_no_refs(self):
900
 
        index = self.make_index(nodes=[
901
 
            ((b'name', ), b'data', ()),
902
 
            ((b'ref', ), b'refdata', ())])
903
 
        self.assertEqual({(index, (b'name', ), b'data'),
904
 
                          (index, (b'ref', ), b'refdata')},
905
 
                         set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
 
860
        index = self.make_index( nodes=[
 
861
            (('name', ), 'data', ()),
 
862
            (('ref', ), 'refdata', ())])
 
863
        self.assertEqual({(index, ('name', ), 'data'),
 
864
            (index, ('ref', ), 'refdata')},
 
865
            set(index.iter_entries_prefix([('name', ), ('ref', )])))
906
866
 
907
867
    def test_iter_key_prefix_1_key_element_refs(self):
908
868
        index = self.make_index(1, nodes=[
909
 
            ((b'name', ), b'data', ([(b'ref', )], )),
910
 
            ((b'ref', ), b'refdata', ([], ))])
911
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
912
 
                          (index, (b'ref', ), b'refdata', ((), ))},
913
 
                         set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
 
869
            (('name', ), 'data', ([('ref', )], )),
 
870
            (('ref', ), 'refdata', ([], ))])
 
871
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
 
872
            (index, ('ref', ), 'refdata', ((), ))},
 
873
            set(index.iter_entries_prefix([('name', ), ('ref', )])))
914
874
 
915
875
    def test_iter_key_prefix_2_key_element_no_refs(self):
916
876
        index = self.make_index(key_elements=2, nodes=[
917
 
            ((b'name', b'fin1'), b'data', ()),
918
 
            ((b'name', b'fin2'), b'beta', ()),
919
 
            ((b'ref', b'erence'), b'refdata', ())])
920
 
        self.assertEqual({(index, (b'name', b'fin1'), b'data'),
921
 
                          (index, (b'ref', b'erence'), b'refdata')},
922
 
                         set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
923
 
        self.assertEqual({(index, (b'name', b'fin1'), b'data'),
924
 
                          (index, (b'name', b'fin2'), b'beta')},
925
 
                         set(index.iter_entries_prefix([(b'name', None)])))
 
877
            (('name', 'fin1'), 'data', ()),
 
878
            (('name', 'fin2'), 'beta', ()),
 
879
            (('ref', 'erence'), 'refdata', ())])
 
880
        self.assertEqual({(index, ('name', 'fin1'), 'data'),
 
881
            (index, ('ref', 'erence'), 'refdata')},
 
882
            set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
 
883
        self.assertEqual({(index, ('name', 'fin1'), 'data'),
 
884
            (index, ('name', 'fin2'), 'beta')},
 
885
            set(index.iter_entries_prefix([('name', None)])))
926
886
 
927
887
    def test_iter_key_prefix_2_key_element_refs(self):
928
888
        index = self.make_index(1, key_elements=2, nodes=[
929
 
            ((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], )),
930
 
            ((b'name', b'fin2'), b'beta', ([], )),
931
 
            ((b'ref', b'erence'), b'refdata', ([], ))])
932
 
        self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
933
 
                          (index, (b'ref', b'erence'), b'refdata', ((), ))},
934
 
                         set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
935
 
        self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
936
 
                          (index, (b'name', b'fin2'), b'beta', ((), ))},
937
 
                         set(index.iter_entries_prefix([(b'name', None)])))
 
889
            (('name', 'fin1'), 'data', ([('ref', 'erence')], )),
 
890
            (('name', 'fin2'), 'beta', ([], )),
 
891
            (('ref', 'erence'), 'refdata', ([], ))])
 
892
        self.assertEqual({(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
 
893
            (index, ('ref', 'erence'), 'refdata', ((), ))},
 
894
            set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
 
895
        self.assertEqual({(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
 
896
            (index, ('name', 'fin2'), 'beta', ((), ))},
 
897
            set(index.iter_entries_prefix([('name', None)])))
938
898
 
939
899
    def test_key_count_empty(self):
940
900
        index = self.make_index()
941
901
        self.assertEqual(0, index.key_count())
942
902
 
943
903
    def test_key_count_one(self):
944
 
        index = self.make_index(nodes=[((b'name', ), b'', ())])
 
904
        index = self.make_index(nodes=[(('name', ), '', ())])
945
905
        self.assertEqual(1, index.key_count())
946
906
 
947
907
    def test_key_count_two(self):
948
908
        index = self.make_index(nodes=[
949
 
            ((b'name', ), b'', ()), ((b'foo', ), b'', ())])
 
909
            (('name', ), '', ()), (('foo', ), '', ())])
950
910
        self.assertEqual(2, index.key_count())
951
911
 
952
912
    def test_read_and_parse_tracks_real_read_value(self):
964
924
 
965
925
    def test_read_and_parse_triggers_buffer_all(self):
966
926
        index = self.make_index(key_elements=2, nodes=[
967
 
            ((b'name', b'fin1'), b'data', ()),
968
 
            ((b'name', b'fin2'), b'beta', ()),
969
 
            ((b'ref', b'erence'), b'refdata', ())])
 
927
            (('name', 'fin1'), 'data', ()),
 
928
            (('name', 'fin2'), 'beta', ()),
 
929
            (('ref', 'erence'), 'refdata', ())])
970
930
        self.assertTrue(index._size > 0)
971
931
        self.assertIs(None, index._nodes)
972
932
        index._read_and_parse([(0, index._size)])
974
934
 
975
935
    def test_validate_bad_index_errors(self):
976
936
        trans = self.get_transport()
977
 
        trans.put_bytes('name', b"not an index\n")
978
 
        idx = _mod_index.GraphIndex(trans, 'name', 13)
979
 
        self.assertRaises(_mod_index.BadIndexFormatSignature, idx.validate)
 
937
        trans.put_bytes('name', "not an index\n")
 
938
        idx = index.GraphIndex(trans, 'name', 13)
 
939
        self.assertRaises(errors.BadIndexFormatSignature, idx.validate)
980
940
 
981
941
    def test_validate_bad_node_refs(self):
982
942
        idx = self.make_index(2)
983
943
        trans = self.get_transport()
984
944
        content = trans.get_bytes('index')
985
945
        # change the options line to end with a rather than a parseable number
986
 
        new_content = content[:-2] + b'a\n\n'
 
946
        new_content = content[:-2] + 'a\n\n'
987
947
        trans.put_bytes('index', new_content)
988
 
        self.assertRaises(_mod_index.BadIndexOptions, idx.validate)
 
948
        self.assertRaises(errors.BadIndexOptions, idx.validate)
989
949
 
990
950
    def test_validate_missing_end_line_empty(self):
991
951
        index = self.make_index(2)
993
953
        content = trans.get_bytes('index')
994
954
        # truncate the last byte
995
955
        trans.put_bytes('index', content[:-1])
996
 
        self.assertRaises(_mod_index.BadIndexData, index.validate)
 
956
        self.assertRaises(errors.BadIndexData, index.validate)
997
957
 
998
958
    def test_validate_missing_end_line_nonempty(self):
999
 
        index = self.make_index(2, nodes=[((b'key', ), b'', ([], []))])
 
959
        index = self.make_index(2, nodes=[(('key', ), '', ([], []))])
1000
960
        trans = self.get_transport()
1001
961
        content = trans.get_bytes('index')
1002
962
        # truncate the last byte
1003
963
        trans.put_bytes('index', content[:-1])
1004
 
        self.assertRaises(_mod_index.BadIndexData, index.validate)
 
964
        self.assertRaises(errors.BadIndexData, index.validate)
1005
965
 
1006
966
    def test_validate_empty(self):
1007
967
        index = self.make_index()
1008
968
        index.validate()
1009
969
 
1010
970
    def test_validate_no_refs_content(self):
1011
 
        index = self.make_index(nodes=[((b'key', ), b'value', ())])
 
971
        index = self.make_index(nodes=[(('key', ), 'value', ())])
1012
972
        index.validate()
1013
973
 
1014
974
    # XXX: external_references tests are duplicated in test_btree_index.  We
1019
979
 
1020
980
    def test_external_references_no_results(self):
1021
981
        index = self.make_index(ref_lists=1, nodes=[
1022
 
            ((b'key',), b'value', ([],))])
 
982
            (('key',), 'value', ([],))])
1023
983
        self.assertEqual(set(), index.external_references(0))
1024
984
 
1025
985
    def test_external_references_missing_ref(self):
1026
 
        missing_key = (b'missing',)
 
986
        missing_key = ('missing',)
1027
987
        index = self.make_index(ref_lists=1, nodes=[
1028
 
            ((b'key',), b'value', ([missing_key],))])
 
988
            (('key',), 'value', ([missing_key],))])
1029
989
        self.assertEqual({missing_key}, index.external_references(0))
1030
990
 
1031
991
    def test_external_references_multiple_ref_lists(self):
1032
 
        missing_key = (b'missing',)
 
992
        missing_key = ('missing',)
1033
993
        index = self.make_index(ref_lists=2, nodes=[
1034
 
            ((b'key',), b'value', ([], [missing_key]))])
 
994
            (('key',), 'value', ([], [missing_key]))])
1035
995
        self.assertEqual(set([]), index.external_references(0))
1036
996
        self.assertEqual({missing_key}, index.external_references(1))
1037
997
 
1038
998
    def test_external_references_two_records(self):
1039
999
        index = self.make_index(ref_lists=1, nodes=[
1040
 
            ((b'key-1',), b'value', ([(b'key-2',)],)),
1041
 
            ((b'key-2',), b'value', ([],)),
 
1000
            (('key-1',), 'value', ([('key-2',)],)),
 
1001
            (('key-2',), 'value', ([],)),
1042
1002
            ])
1043
1003
        self.assertEqual(set([]), index.external_references(0))
1044
1004
 
1045
1005
    def test__find_ancestors(self):
1046
 
        key1 = (b'key-1',)
1047
 
        key2 = (b'key-2',)
 
1006
        key1 = ('key-1',)
 
1007
        key2 = ('key-2',)
1048
1008
        index = self.make_index(ref_lists=1, key_elements=1, nodes=[
1049
 
            (key1, b'value', ([key2],)),
1050
 
            (key2, b'value', ([],)),
 
1009
            (key1, 'value', ([key2],)),
 
1010
            (key2, 'value', ([],)),
1051
1011
            ])
1052
1012
        parent_map = {}
1053
1013
        missing_keys = set()
1054
 
        search_keys = index._find_ancestors(
1055
 
            [key1], 0, parent_map, missing_keys)
 
1014
        search_keys = index._find_ancestors([key1], 0, parent_map, missing_keys)
1056
1015
        self.assertEqual({key1: (key2,)}, parent_map)
1057
1016
        self.assertEqual(set(), missing_keys)
1058
1017
        self.assertEqual({key2}, search_keys)
1063
1022
        self.assertEqual(set(), search_keys)
1064
1023
 
1065
1024
    def test__find_ancestors_w_missing(self):
1066
 
        key1 = (b'key-1',)
1067
 
        key2 = (b'key-2',)
1068
 
        key3 = (b'key-3',)
 
1025
        key1 = ('key-1',)
 
1026
        key2 = ('key-2',)
 
1027
        key3 = ('key-3',)
1069
1028
        index = self.make_index(ref_lists=1, key_elements=1, nodes=[
1070
 
            (key1, b'value', ([key2],)),
1071
 
            (key2, b'value', ([],)),
 
1029
            (key1, 'value', ([key2],)),
 
1030
            (key2, 'value', ([],)),
1072
1031
            ])
1073
1032
        parent_map = {}
1074
1033
        missing_keys = set()
1079
1038
        self.assertEqual(set(), search_keys)
1080
1039
 
1081
1040
    def test__find_ancestors_dont_search_known(self):
1082
 
        key1 = (b'key-1',)
1083
 
        key2 = (b'key-2',)
1084
 
        key3 = (b'key-3',)
 
1041
        key1 = ('key-1',)
 
1042
        key2 = ('key-2',)
 
1043
        key3 = ('key-3',)
1085
1044
        index = self.make_index(ref_lists=1, key_elements=1, nodes=[
1086
 
            (key1, b'value', ([key2],)),
1087
 
            (key2, b'value', ([key3],)),
1088
 
            (key3, b'value', ([],)),
 
1045
            (key1, 'value', ([key2],)),
 
1046
            (key2, 'value', ([key3],)),
 
1047
            (key3, 'value', ([],)),
1089
1048
            ])
1090
1049
        # We already know about key2, so we won't try to search for key3
1091
1050
        parent_map = {key2: (key3,)}
1097
1056
        self.assertEqual(set(), search_keys)
1098
1057
 
1099
1058
    def test_supports_unlimited_cache(self):
1100
 
        builder = _mod_index.GraphIndexBuilder(0, key_elements=1)
 
1059
        builder = index.GraphIndexBuilder(0, key_elements=1)
1101
1060
        stream = builder.finish()
1102
1061
        trans = self.get_transport()
1103
1062
        size = trans.put_file('index', stream)
1104
1063
        # It doesn't matter what unlimited_cache does here, just that it can be
1105
1064
        # passed
1106
 
        idx = _mod_index.GraphIndex(trans, 'index', size, unlimited_cache=True)
 
1065
        idx = index.GraphIndex(trans, 'index', size, unlimited_cache=True)
1107
1066
 
1108
1067
 
1109
1068
class TestCombinedGraphIndex(tests.TestCaseWithMemoryTransport):
1110
1069
 
1111
1070
    def make_index(self, name, ref_lists=0, key_elements=1, nodes=[]):
1112
 
        builder = _mod_index.GraphIndexBuilder(
1113
 
            ref_lists, key_elements=key_elements)
 
1071
        builder = index.GraphIndexBuilder(ref_lists, key_elements=key_elements)
1114
1072
        for key, value, references in nodes:
1115
1073
            builder.add_node(key, value, references)
1116
1074
        stream = builder.finish()
1117
1075
        trans = self.get_transport()
1118
1076
        size = trans.put_file(name, stream)
1119
 
        return _mod_index.GraphIndex(trans, name, size)
 
1077
        return index.GraphIndex(trans, name, size)
1120
1078
 
1121
1079
    def make_combined_index_with_missing(self, missing=['1', '2']):
1122
1080
        """Create a CombinedGraphIndex which will have missing indexes.
1128
1086
        :param missing: The underlying indexes to delete
1129
1087
        :return: (CombinedGraphIndex, reload_counter)
1130
1088
        """
1131
 
        idx1 = self.make_index('1', nodes=[((b'1',), b'', ())])
1132
 
        idx2 = self.make_index('2', nodes=[((b'2',), b'', ())])
 
1089
        idx1 = self.make_index('1', nodes=[(('1',), '', ())])
 
1090
        idx2 = self.make_index('2', nodes=[(('2',), '', ())])
1133
1091
        idx3 = self.make_index('3', nodes=[
1134
 
            ((b'1',), b'', ()),
1135
 
            ((b'2',), b'', ())])
 
1092
            (('1',), '', ()),
 
1093
            (('2',), '', ())])
1136
1094
 
1137
1095
        # total_reloads, num_changed, num_unchanged
1138
1096
        reload_counter = [0, 0, 0]
1139
 
 
1140
1097
        def reload():
1141
1098
            reload_counter[0] += 1
1142
1099
            new_indices = [idx3]
1146
1103
            reload_counter[1] += 1
1147
1104
            idx._indices[:] = new_indices
1148
1105
            return True
1149
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2], reload_func=reload)
 
1106
        idx = index.CombinedGraphIndex([idx1, idx2], reload_func=reload)
1150
1107
        trans = self.get_transport()
1151
1108
        for fname in missing:
1152
1109
            trans.delete(fname)
1154
1111
 
1155
1112
    def test_open_missing_index_no_error(self):
1156
1113
        trans = self.get_transport()
1157
 
        idx1 = _mod_index.GraphIndex(trans, 'missing', 100)
1158
 
        idx = _mod_index.CombinedGraphIndex([idx1])
 
1114
        idx1 = index.GraphIndex(trans, 'missing', 100)
 
1115
        idx = index.CombinedGraphIndex([idx1])
1159
1116
 
1160
1117
    def test_add_index(self):
1161
 
        idx = _mod_index.CombinedGraphIndex([])
1162
 
        idx1 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
 
1118
        idx = index.CombinedGraphIndex([])
 
1119
        idx1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1163
1120
        idx.insert_index(0, idx1)
1164
 
        self.assertEqual([(idx1, (b'key', ), b'')],
 
1121
        self.assertEqual([(idx1, ('key', ), '')],
1165
1122
                         list(idx.iter_all_entries()))
1166
1123
 
1167
1124
    def test_clear_cache(self):
1179
1136
                log.append(self._index)
1180
1137
                return self._index.clear_cache()
1181
1138
 
1182
 
        idx = _mod_index.CombinedGraphIndex([])
1183
 
        idx1 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
 
1139
        idx = index.CombinedGraphIndex([])
 
1140
        idx1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1184
1141
        idx.insert_index(0, ClearCacheProxy(idx1))
1185
 
        idx2 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
 
1142
        idx2 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1186
1143
        idx.insert_index(1, ClearCacheProxy(idx2))
1187
1144
        # CombinedGraphIndex should call 'clear_cache()' on all children
1188
1145
        idx.clear_cache()
1189
1146
        self.assertEqual(sorted([idx1, idx2]), sorted(log))
1190
1147
 
1191
1148
    def test_iter_all_entries_empty(self):
1192
 
        idx = _mod_index.CombinedGraphIndex([])
 
1149
        idx = index.CombinedGraphIndex([])
1193
1150
        self.assertEqual([], list(idx.iter_all_entries()))
1194
1151
 
1195
1152
    def test_iter_all_entries_children_empty(self):
1196
1153
        idx1 = self.make_index('name')
1197
 
        idx = _mod_index.CombinedGraphIndex([idx1])
 
1154
        idx = index.CombinedGraphIndex([idx1])
1198
1155
        self.assertEqual([], list(idx.iter_all_entries()))
1199
1156
 
1200
1157
    def test_iter_all_entries_simple(self):
1201
 
        idx1 = self.make_index('name', nodes=[((b'name', ), b'data', ())])
1202
 
        idx = _mod_index.CombinedGraphIndex([idx1])
1203
 
        self.assertEqual([(idx1, (b'name', ), b'data')],
1204
 
                         list(idx.iter_all_entries()))
 
1158
        idx1 = self.make_index('name', nodes=[(('name', ), 'data', ())])
 
1159
        idx = index.CombinedGraphIndex([idx1])
 
1160
        self.assertEqual([(idx1, ('name', ), 'data')],
 
1161
            list(idx.iter_all_entries()))
1205
1162
 
1206
1163
    def test_iter_all_entries_two_indices(self):
1207
 
        idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
1208
 
        idx2 = self.make_index('name2', nodes=[((b'2', ), b'', ())])
1209
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1210
 
        self.assertEqual([(idx1, (b'name', ), b'data'),
1211
 
                          (idx2, (b'2', ), b'')],
 
1164
        idx1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
 
1165
        idx2 = self.make_index('name2', nodes=[(('2', ), '', ())])
 
1166
        idx = index.CombinedGraphIndex([idx1, idx2])
 
1167
        self.assertEqual([(idx1, ('name', ), 'data'),
 
1168
                          (idx2, ('2', ), '')],
1212
1169
                         list(idx.iter_all_entries()))
1213
1170
 
1214
1171
    def test_iter_entries_two_indices_dup_key(self):
1215
 
        idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
1216
 
        idx2 = self.make_index('name2', nodes=[((b'name', ), b'data', ())])
1217
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1218
 
        self.assertEqual([(idx1, (b'name', ), b'data')],
1219
 
                         list(idx.iter_entries([(b'name', )])))
 
1172
        idx1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
 
1173
        idx2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
 
1174
        idx = index.CombinedGraphIndex([idx1, idx2])
 
1175
        self.assertEqual([(idx1, ('name', ), 'data')],
 
1176
                         list(idx.iter_entries([('name', )])))
1220
1177
 
1221
1178
    def test_iter_all_entries_two_indices_dup_key(self):
1222
 
        idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
1223
 
        idx2 = self.make_index('name2', nodes=[((b'name', ), b'data', ())])
1224
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1225
 
        self.assertEqual([(idx1, (b'name', ), b'data')],
 
1179
        idx1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
 
1180
        idx2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
 
1181
        idx = index.CombinedGraphIndex([idx1, idx2])
 
1182
        self.assertEqual([(idx1, ('name', ), 'data')],
1226
1183
                         list(idx.iter_all_entries()))
1227
1184
 
1228
1185
    def test_iter_key_prefix_2_key_element_refs(self):
1229
1186
        idx1 = self.make_index('1', 1, key_elements=2, nodes=[
1230
 
            ((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], ))])
 
1187
                (('name', 'fin1'), 'data', ([('ref', 'erence')], ))])
1231
1188
        idx2 = self.make_index('2', 1, key_elements=2, nodes=[
1232
 
            ((b'name', b'fin2'), b'beta', ([], )),
1233
 
            ((b'ref', b'erence'), b'refdata', ([], ))])
1234
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1235
 
        self.assertEqual({(idx1, (b'name', b'fin1'), b'data',
1236
 
                           (((b'ref', b'erence'),),)),
1237
 
                          (idx2, (b'ref', b'erence'), b'refdata', ((), ))},
1238
 
                         set(idx.iter_entries_prefix([(b'name', b'fin1'),
1239
 
                                                      (b'ref', b'erence')])))
1240
 
        self.assertEqual({(idx1, (b'name', b'fin1'), b'data',
1241
 
                           (((b'ref', b'erence'),),)),
1242
 
                          (idx2, (b'name', b'fin2'), b'beta', ((), ))},
1243
 
                         set(idx.iter_entries_prefix([(b'name', None)])))
 
1189
                (('name', 'fin2'), 'beta', ([], )),
 
1190
                (('ref', 'erence'), 'refdata', ([], ))])
 
1191
        idx = index.CombinedGraphIndex([idx1, idx2])
 
1192
        self.assertEqual({(idx1, ('name', 'fin1'), 'data',
 
1193
                               ((('ref', 'erence'),),)),
 
1194
                              (idx2, ('ref', 'erence'), 'refdata', ((), ))},
 
1195
                         set(idx.iter_entries_prefix([('name', 'fin1'),
 
1196
                                                        ('ref', 'erence')])))
 
1197
        self.assertEqual({(idx1, ('name', 'fin1'), 'data',
 
1198
                               ((('ref', 'erence'),),)),
 
1199
                              (idx2, ('name', 'fin2'), 'beta', ((), ))},
 
1200
                         set(idx.iter_entries_prefix([('name', None)])))
1244
1201
 
1245
1202
    def test_iter_nothing_empty(self):
1246
 
        idx = _mod_index.CombinedGraphIndex([])
 
1203
        idx = index.CombinedGraphIndex([])
1247
1204
        self.assertEqual([], list(idx.iter_entries([])))
1248
1205
 
1249
1206
    def test_iter_nothing_children_empty(self):
1250
1207
        idx1 = self.make_index('name')
1251
 
        idx = _mod_index.CombinedGraphIndex([idx1])
 
1208
        idx = index.CombinedGraphIndex([idx1])
1252
1209
        self.assertEqual([], list(idx.iter_entries([])))
1253
1210
 
1254
1211
    def test_iter_all_keys(self):
1255
 
        idx1 = self.make_index('1', 1, nodes=[((b'name', ), b'data',
1256
 
                                               ([(b'ref', )], ))])
1257
 
        idx2 = self.make_index(
1258
 
            '2', 1, nodes=[((b'ref', ), b'refdata', ((), ))])
1259
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1260
 
        self.assertEqual({(idx1, (b'name', ), b'data', (((b'ref', ), ), )),
1261
 
                          (idx2, (b'ref', ), b'refdata', ((), ))},
1262
 
                         set(idx.iter_entries([(b'name', ), (b'ref', )])))
 
1212
        idx1 = self.make_index('1', 1, nodes=[(('name', ), 'data',
 
1213
                                               ([('ref', )], ))])
 
1214
        idx2 = self.make_index('2', 1, nodes=[(('ref', ), 'refdata', ((), ))])
 
1215
        idx = index.CombinedGraphIndex([idx1, idx2])
 
1216
        self.assertEqual({(idx1, ('name', ), 'data', ((('ref', ), ), )),
 
1217
                              (idx2, ('ref', ), 'refdata', ((), ))},
 
1218
                         set(idx.iter_entries([('name', ), ('ref', )])))
1263
1219
 
1264
1220
    def test_iter_all_keys_dup_entry(self):
1265
 
        idx1 = self.make_index('1', 1, nodes=[((b'name', ), b'data',
1266
 
                                               ([(b'ref', )], )),
1267
 
                                              ((b'ref', ), b'refdata', ([], ))])
1268
 
        idx2 = self.make_index(
1269
 
            '2', 1, nodes=[((b'ref', ), b'refdata', ([], ))])
1270
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1271
 
        self.assertEqual({(idx1, (b'name', ), b'data', (((b'ref',),),)),
1272
 
                          (idx1, (b'ref', ), b'refdata', ((), ))},
1273
 
                         set(idx.iter_entries([(b'name', ), (b'ref', )])))
 
1221
        idx1 = self.make_index('1', 1, nodes=[(('name', ), 'data',
 
1222
                                                 ([('ref', )], )),
 
1223
                                                (('ref', ), 'refdata', ([], ))])
 
1224
        idx2 = self.make_index('2', 1, nodes=[(('ref', ), 'refdata', ([], ))])
 
1225
        idx = index.CombinedGraphIndex([idx1, idx2])
 
1226
        self.assertEqual({(idx1, ('name', ), 'data', ((('ref',),),)),
 
1227
                              (idx1, ('ref', ), 'refdata', ((), ))},
 
1228
                         set(idx.iter_entries([('name', ), ('ref', )])))
1274
1229
 
1275
1230
    def test_iter_missing_entry_empty(self):
1276
 
        idx = _mod_index.CombinedGraphIndex([])
 
1231
        idx = index.CombinedGraphIndex([])
1277
1232
        self.assertEqual([], list(idx.iter_entries([('a', )])))
1278
1233
 
1279
1234
    def test_iter_missing_entry_one_index(self):
1280
1235
        idx1 = self.make_index('1')
1281
 
        idx = _mod_index.CombinedGraphIndex([idx1])
1282
 
        self.assertEqual([], list(idx.iter_entries([(b'a', )])))
 
1236
        idx = index.CombinedGraphIndex([idx1])
 
1237
        self.assertEqual([], list(idx.iter_entries([('a', )])))
1283
1238
 
1284
1239
    def test_iter_missing_entry_two_index(self):
1285
1240
        idx1 = self.make_index('1')
1286
1241
        idx2 = self.make_index('2')
1287
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
 
1242
        idx = index.CombinedGraphIndex([idx1, idx2])
1288
1243
        self.assertEqual([], list(idx.iter_entries([('a', )])))
1289
1244
 
1290
1245
    def test_iter_entry_present_one_index_only(self):
1291
 
        idx1 = self.make_index('1', nodes=[((b'key', ), b'', ())])
 
1246
        idx1 = self.make_index('1', nodes=[(('key', ), '', ())])
1292
1247
        idx2 = self.make_index('2', nodes=[])
1293
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1294
 
        self.assertEqual([(idx1, (b'key', ), b'')],
1295
 
                         list(idx.iter_entries([(b'key', )])))
 
1248
        idx = index.CombinedGraphIndex([idx1, idx2])
 
1249
        self.assertEqual([(idx1, ('key', ), '')],
 
1250
                         list(idx.iter_entries([('key', )])))
1296
1251
        # and in the other direction
1297
 
        idx = _mod_index.CombinedGraphIndex([idx2, idx1])
1298
 
        self.assertEqual([(idx1, (b'key', ), b'')],
1299
 
                         list(idx.iter_entries([(b'key', )])))
 
1252
        idx = index.CombinedGraphIndex([idx2, idx1])
 
1253
        self.assertEqual([(idx1, ('key', ), '')],
 
1254
                         list(idx.iter_entries([('key', )])))
1300
1255
 
1301
1256
    def test_key_count_empty(self):
1302
1257
        idx1 = self.make_index('1', nodes=[])
1303
1258
        idx2 = self.make_index('2', nodes=[])
1304
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
 
1259
        idx = index.CombinedGraphIndex([idx1, idx2])
1305
1260
        self.assertEqual(0, idx.key_count())
1306
1261
 
1307
1262
    def test_key_count_sums_index_keys(self):
1308
1263
        idx1 = self.make_index('1', nodes=[
1309
 
            ((b'1',), b'', ()),
1310
 
            ((b'2',), b'', ())])
1311
 
        idx2 = self.make_index('2', nodes=[((b'1',), b'', ())])
1312
 
        idx = _mod_index.CombinedGraphIndex([idx1, idx2])
 
1264
            (('1',), '', ()),
 
1265
            (('2',), '', ())])
 
1266
        idx2 = self.make_index('2', nodes=[(('1',), '', ())])
 
1267
        idx = index.CombinedGraphIndex([idx1, idx2])
1313
1268
        self.assertEqual(3, idx.key_count())
1314
1269
 
1315
1270
    def test_validate_bad_child_index_errors(self):
1316
1271
        trans = self.get_transport()
1317
 
        trans.put_bytes('name', b"not an index\n")
1318
 
        idx1 = _mod_index.GraphIndex(trans, 'name', 13)
1319
 
        idx = _mod_index.CombinedGraphIndex([idx1])
1320
 
        self.assertRaises(_mod_index.BadIndexFormatSignature, idx.validate)
 
1272
        trans.put_bytes('name', "not an index\n")
 
1273
        idx1 = index.GraphIndex(trans, 'name', 13)
 
1274
        idx = index.CombinedGraphIndex([idx1])
 
1275
        self.assertRaises(errors.BadIndexFormatSignature, idx.validate)
1321
1276
 
1322
1277
    def test_validate_empty(self):
1323
 
        idx = _mod_index.CombinedGraphIndex([])
 
1278
        idx = index.CombinedGraphIndex([])
1324
1279
        idx.validate()
1325
1280
 
1326
1281
    def test_key_count_reloads(self):
1345
1300
 
1346
1301
    def test_iter_entries_reloads(self):
1347
1302
        index, reload_counter = self.make_combined_index_with_missing()
1348
 
        result = list(index.iter_entries([(b'1',), (b'2',), (b'3',)]))
 
1303
        result = list(index.iter_entries([('1',), ('2',), ('3',)]))
1349
1304
        index3 = index._indices[0]
1350
 
        self.assertEqual({(index3, (b'1',), b''), (index3, (b'2',), b'')},
1351
 
                         set(result))
 
1305
        self.assertEqual([(index3, ('1',), ''), (index3, ('2',), '')],
 
1306
                         result)
1352
1307
        self.assertEqual([1, 1, 0], reload_counter)
1353
1308
 
1354
1309
    def test_iter_entries_reloads_midway(self):
1356
1311
        # through
1357
1312
        index, reload_counter = self.make_combined_index_with_missing(['2'])
1358
1313
        index1, index2 = index._indices
1359
 
        result = list(index.iter_entries([(b'1',), (b'2',), (b'3',)]))
 
1314
        result = list(index.iter_entries([('1',), ('2',), ('3',)]))
1360
1315
        index3 = index._indices[0]
1361
 
        # We had already yielded b'1', so we just go on to the next, we should
1362
 
        # not yield b'1' twice.
1363
 
        self.assertEqual([(index1, (b'1',), b''), (index3, (b'2',), b'')],
 
1316
        # We had already yielded '1', so we just go on to the next, we should
 
1317
        # not yield '1' twice.
 
1318
        self.assertEqual([(index1, ('1',), ''), (index3, ('2',), '')],
1364
1319
                         result)
1365
1320
        self.assertEqual([1, 1, 0], reload_counter)
1366
1321
 
1372
1327
 
1373
1328
    def test_iter_entries_reloads_and_fails(self):
1374
1329
        index, reload_counter = self.make_combined_index_with_missing(
1375
 
            ['1', '2', '3'])
 
1330
                                    ['1', '2', '3'])
1376
1331
        self.assertListRaises(errors.NoSuchFile, index.iter_entries, [('3',)])
1377
1332
        self.assertEqual([2, 1, 1], reload_counter)
1378
1333
 
1380
1335
        index, reload_counter = self.make_combined_index_with_missing()
1381
1336
        result = list(index.iter_all_entries())
1382
1337
        index3 = index._indices[0]
1383
 
        self.assertEqual({(index3, (b'1',), b''), (index3, (b'2',), b'')},
1384
 
                         set(result))
 
1338
        self.assertEqual([(index3, ('1',), ''), (index3, ('2',), '')],
 
1339
                         result)
1385
1340
        self.assertEqual([1, 1, 0], reload_counter)
1386
1341
 
1387
1342
    def test_iter_all_entries_reloads_midway(self):
1391
1346
        index3 = index._indices[0]
1392
1347
        # We had already yielded '1', so we just go on to the next, we should
1393
1348
        # not yield '1' twice.
1394
 
        self.assertEqual([(index1, (b'1',), b''), (index3, (b'2',), b'')],
 
1349
        self.assertEqual([(index1, ('1',), ''), (index3, ('2',), '')],
1395
1350
                         result)
1396
1351
        self.assertEqual([1, 1, 0], reload_counter)
1397
1352
 
1402
1357
 
1403
1358
    def test_iter_all_entries_reloads_and_fails(self):
1404
1359
        index, reload_counter = self.make_combined_index_with_missing(
1405
 
            ['1', '2', '3'])
 
1360
                                    ['1', '2', '3'])
1406
1361
        self.assertListRaises(errors.NoSuchFile, index.iter_all_entries)
1407
1362
 
1408
1363
    def test_iter_entries_prefix_reloads(self):
1409
1364
        index, reload_counter = self.make_combined_index_with_missing()
1410
 
        result = list(index.iter_entries_prefix([(b'1',)]))
 
1365
        result = list(index.iter_entries_prefix([('1',)]))
1411
1366
        index3 = index._indices[0]
1412
 
        self.assertEqual([(index3, (b'1',), b'')], result)
 
1367
        self.assertEqual([(index3, ('1',), '')], result)
1413
1368
        self.assertEqual([1, 1, 0], reload_counter)
1414
1369
 
1415
1370
    def test_iter_entries_prefix_reloads_midway(self):
1416
1371
        index, reload_counter = self.make_combined_index_with_missing(['2'])
1417
1372
        index1, index2 = index._indices
1418
 
        result = list(index.iter_entries_prefix([(b'1',)]))
 
1373
        result = list(index.iter_entries_prefix([('1',)]))
1419
1374
        index3 = index._indices[0]
1420
 
        # We had already yielded b'1', so we just go on to the next, we should
1421
 
        # not yield b'1' twice.
1422
 
        self.assertEqual([(index1, (b'1',), b'')], result)
 
1375
        # We had already yielded '1', so we just go on to the next, we should
 
1376
        # not yield '1' twice.
 
1377
        self.assertEqual([(index1, ('1',), '')], result)
1423
1378
        self.assertEqual([1, 1, 0], reload_counter)
1424
1379
 
1425
1380
    def test_iter_entries_prefix_no_reload(self):
1426
1381
        index, reload_counter = self.make_combined_index_with_missing()
1427
1382
        index._reload_func = None
1428
1383
        self.assertListRaises(errors.NoSuchFile, index.iter_entries_prefix,
1429
 
                              [(b'1',)])
 
1384
                                                 [('1',)])
1430
1385
 
1431
1386
    def test_iter_entries_prefix_reloads_and_fails(self):
1432
1387
        index, reload_counter = self.make_combined_index_with_missing(
1433
 
            ['1', '2', '3'])
 
1388
                                    ['1', '2', '3'])
1434
1389
        self.assertListRaises(errors.NoSuchFile, index.iter_entries_prefix,
1435
 
                              [(b'1',)])
 
1390
                                                 [('1',)])
 
1391
 
1436
1392
 
1437
1393
    def make_index_with_simple_nodes(self, name, num_nodes=1):
1438
1394
        """Make an index named after 'name', with keys named after 'name' too.
1440
1396
        Nodes will have a value of '' and no references.
1441
1397
        """
1442
1398
        nodes = [
1443
 
            ((('index-%s-key-%s' % (name, n)).encode('ascii'),), b'', ())
1444
 
            for n in range(1, num_nodes + 1)]
 
1399
            (('index-%s-key-%s' % (name, n),), '', ())
 
1400
            for n in range(1, num_nodes+1)]
1445
1401
        return self.make_index('index-%s' % name, 0, nodes=nodes)
1446
1402
 
1447
1403
    def test_reorder_after_iter_entries(self):
1448
1404
        # Four indices: [key1] in idx1, [key2,key3] in idx2, [] in idx3,
1449
1405
        # [key4] in idx4.
1450
 
        idx = _mod_index.CombinedGraphIndex([])
1451
 
        idx.insert_index(0, self.make_index_with_simple_nodes('1'), b'1')
1452
 
        idx.insert_index(1, self.make_index_with_simple_nodes('2'), b'2')
1453
 
        idx.insert_index(2, self.make_index_with_simple_nodes('3'), b'3')
1454
 
        idx.insert_index(3, self.make_index_with_simple_nodes('4'), b'4')
 
1406
        idx = index.CombinedGraphIndex([])
 
1407
        idx.insert_index(0, self.make_index_with_simple_nodes('1'), '1')
 
1408
        idx.insert_index(1, self.make_index_with_simple_nodes('2'), '2')
 
1409
        idx.insert_index(2, self.make_index_with_simple_nodes('3'), '3')
 
1410
        idx.insert_index(3, self.make_index_with_simple_nodes('4'), '4')
1455
1411
        idx1, idx2, idx3, idx4 = idx._indices
1456
1412
        # Query a key from idx4 and idx2.
1457
1413
        self.assertLength(2, list(idx.iter_entries(
1458
 
            [(b'index-4-key-1',), (b'index-2-key-1',)])))
 
1414
            [('index-4-key-1',), ('index-2-key-1',)])))
1459
1415
        # Now idx2 and idx4 should be moved to the front (and idx1 should
1460
1416
        # still be before idx3).
1461
1417
        self.assertEqual([idx2, idx4, idx1, idx3], idx._indices)
1462
 
        self.assertEqual([b'2', b'4', b'1', b'3'], idx._index_names)
 
1418
        self.assertEqual(['2', '4', '1', '3'], idx._index_names)
1463
1419
 
1464
1420
    def test_reorder_propagates_to_siblings(self):
1465
1421
        # Two CombinedGraphIndex objects, with the same number of indicies with
1466
1422
        # matching names.
1467
 
        cgi1 = _mod_index.CombinedGraphIndex([])
1468
 
        cgi2 = _mod_index.CombinedGraphIndex([])
 
1423
        cgi1 = index.CombinedGraphIndex([])
 
1424
        cgi2 = index.CombinedGraphIndex([])
1469
1425
        cgi1.insert_index(0, self.make_index_with_simple_nodes('1-1'), 'one')
1470
1426
        cgi1.insert_index(1, self.make_index_with_simple_nodes('1-2'), 'two')
1471
1427
        cgi2.insert_index(0, self.make_index_with_simple_nodes('2-1'), 'one')
1473
1429
        index2_1, index2_2 = cgi2._indices
1474
1430
        cgi1.set_sibling_indices([cgi2])
1475
1431
        # Trigger a reordering in cgi1.  cgi2 will be reordered as well.
1476
 
        list(cgi1.iter_entries([(b'index-1-2-key-1',)]))
 
1432
        list(cgi1.iter_entries([('index-1-2-key-1',)]))
1477
1433
        self.assertEqual([index2_2, index2_1], cgi2._indices)
1478
1434
        self.assertEqual(['two', 'one'], cgi2._index_names)
1479
1435
 
1497
1453
        self.assertRaises(errors.NoSuchFile, idx.validate)
1498
1454
 
1499
1455
    def test_find_ancestors_across_indexes(self):
1500
 
        key1 = (b'key-1',)
1501
 
        key2 = (b'key-2',)
1502
 
        key3 = (b'key-3',)
1503
 
        key4 = (b'key-4',)
 
1456
        key1 = ('key-1',)
 
1457
        key2 = ('key-2',)
 
1458
        key3 = ('key-3',)
 
1459
        key4 = ('key-4',)
1504
1460
        index1 = self.make_index('12', ref_lists=1, nodes=[
1505
 
            (key1, b'value', ([],)),
1506
 
            (key2, b'value', ([key1],)),
 
1461
            (key1, 'value', ([],)),
 
1462
            (key2, 'value', ([key1],)),
1507
1463
            ])
1508
1464
        index2 = self.make_index('34', ref_lists=1, nodes=[
1509
 
            (key3, b'value', ([key2],)),
1510
 
            (key4, b'value', ([key3],)),
 
1465
            (key3, 'value', ([key2],)),
 
1466
            (key4, 'value', ([key3],)),
1511
1467
            ])
1512
 
        c_index = _mod_index.CombinedGraphIndex([index1, index2])
 
1468
        c_index = index.CombinedGraphIndex([index1, index2])
1513
1469
        parent_map, missing_keys = c_index.find_ancestry([key1], 0)
1514
1470
        self.assertEqual({key1: ()}, parent_map)
1515
1471
        self.assertEqual(set(), missing_keys)
1521
1477
        self.assertEqual(set(), missing_keys)
1522
1478
 
1523
1479
    def test_find_ancestors_missing_keys(self):
1524
 
        key1 = (b'key-1',)
1525
 
        key2 = (b'key-2',)
1526
 
        key3 = (b'key-3',)
1527
 
        key4 = (b'key-4',)
 
1480
        key1 = ('key-1',)
 
1481
        key2 = ('key-2',)
 
1482
        key3 = ('key-3',)
 
1483
        key4 = ('key-4',)
1528
1484
        index1 = self.make_index('12', ref_lists=1, nodes=[
1529
 
            (key1, b'value', ([],)),
1530
 
            (key2, b'value', ([key1],)),
 
1485
            (key1, 'value', ([],)),
 
1486
            (key2, 'value', ([key1],)),
1531
1487
            ])
1532
1488
        index2 = self.make_index('34', ref_lists=1, nodes=[
1533
 
            (key3, b'value', ([key2],)),
 
1489
            (key3, 'value', ([key2],)),
1534
1490
            ])
1535
 
        c_index = _mod_index.CombinedGraphIndex([index1, index2])
 
1491
        c_index = index.CombinedGraphIndex([index1, index2])
1536
1492
        # Searching for a key which is actually not present at all should
1537
1493
        # eventually converge
1538
1494
        parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1540
1496
        self.assertEqual({key4}, missing_keys)
1541
1497
 
1542
1498
    def test_find_ancestors_no_indexes(self):
1543
 
        c_index = _mod_index.CombinedGraphIndex([])
1544
 
        key1 = (b'key-1',)
 
1499
        c_index = index.CombinedGraphIndex([])
 
1500
        key1 = ('key-1',)
1545
1501
        parent_map, missing_keys = c_index.find_ancestry([key1], 0)
1546
1502
        self.assertEqual({}, parent_map)
1547
1503
        self.assertEqual({key1}, missing_keys)
1548
1504
 
1549
1505
    def test_find_ancestors_ghost_parent(self):
1550
 
        key1 = (b'key-1',)
1551
 
        key2 = (b'key-2',)
1552
 
        key3 = (b'key-3',)
1553
 
        key4 = (b'key-4',)
 
1506
        key1 = ('key-1',)
 
1507
        key2 = ('key-2',)
 
1508
        key3 = ('key-3',)
 
1509
        key4 = ('key-4',)
1554
1510
        index1 = self.make_index('12', ref_lists=1, nodes=[
1555
 
            (key1, b'value', ([],)),
1556
 
            (key2, b'value', ([key1],)),
 
1511
            (key1, 'value', ([],)),
 
1512
            (key2, 'value', ([key1],)),
1557
1513
            ])
1558
1514
        index2 = self.make_index('34', ref_lists=1, nodes=[
1559
 
            (key4, b'value', ([key2, key3],)),
 
1515
            (key4, 'value', ([key2, key3],)),
1560
1516
            ])
1561
 
        c_index = _mod_index.CombinedGraphIndex([index1, index2])
 
1517
        c_index = index.CombinedGraphIndex([index1, index2])
1562
1518
        # Searching for a key which is actually not present at all should
1563
1519
        # eventually converge
1564
1520
        parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1570
1526
        idx = self.make_index('test', ref_lists=1, key_elements=1, nodes=[])
1571
1527
        parent_map = {}
1572
1528
        missing_keys = set()
1573
 
        search_keys = idx._find_ancestors([(b'one',), (b'two',)], 0, parent_map,
 
1529
        search_keys = idx._find_ancestors([('one',), ('two',)], 0, parent_map,
1574
1530
                                          missing_keys)
1575
1531
        self.assertEqual(set(), search_keys)
1576
1532
        self.assertEqual({}, parent_map)
1577
 
        self.assertEqual({(b'one',), (b'two',)}, missing_keys)
 
1533
        self.assertEqual({('one',), ('two',)}, missing_keys)
1578
1534
 
1579
1535
 
1580
1536
class TestInMemoryGraphIndex(tests.TestCaseWithMemoryTransport):
1581
1537
 
1582
1538
    def make_index(self, ref_lists=0, key_elements=1, nodes=[]):
1583
 
        result = _mod_index.InMemoryGraphIndex(
1584
 
            ref_lists, key_elements=key_elements)
 
1539
        result = index.InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1585
1540
        result.add_nodes(nodes)
1586
1541
        return result
1587
1542
 
1588
1543
    def test_add_nodes_no_refs(self):
1589
1544
        index = self.make_index(0)
1590
 
        index.add_nodes([((b'name', ), b'data')])
1591
 
        index.add_nodes([((b'name2', ), b''), ((b'name3', ), b'')])
 
1545
        index.add_nodes([(('name', ), 'data')])
 
1546
        index.add_nodes([(('name2', ), ''), (('name3', ), '')])
1592
1547
        self.assertEqual({
1593
 
            (index, (b'name', ), b'data'),
1594
 
            (index, (b'name2', ), b''),
1595
 
            (index, (b'name3', ), b''),
 
1548
            (index, ('name', ), 'data'),
 
1549
            (index, ('name2', ), ''),
 
1550
            (index, ('name3', ), ''),
1596
1551
            }, set(index.iter_all_entries()))
1597
1552
 
1598
1553
    def test_add_nodes(self):
1599
1554
        index = self.make_index(1)
1600
 
        index.add_nodes([((b'name', ), b'data', ([],))])
1601
 
        index.add_nodes([((b'name2', ), b'', ([],)),
1602
 
                         ((b'name3', ), b'', ([(b'r', )],))])
 
1555
        index.add_nodes([(('name', ), 'data', ([],))])
 
1556
        index.add_nodes([(('name2', ), '', ([],)), (('name3', ), '', ([('r', )],))])
1603
1557
        self.assertEqual({
1604
 
            (index, (b'name', ), b'data', ((),)),
1605
 
            (index, (b'name2', ), b'', ((),)),
1606
 
            (index, (b'name3', ), b'', (((b'r', ), ), )),
 
1558
            (index, ('name', ), 'data', ((),)),
 
1559
            (index, ('name2', ), '', ((),)),
 
1560
            (index, ('name3', ), '', ((('r', ), ), )),
1607
1561
            }, set(index.iter_all_entries()))
1608
1562
 
1609
1563
    def test_iter_all_entries_empty(self):
1611
1565
        self.assertEqual([], list(index.iter_all_entries()))
1612
1566
 
1613
1567
    def test_iter_all_entries_simple(self):
1614
 
        index = self.make_index(nodes=[((b'name', ), b'data')])
1615
 
        self.assertEqual([(index, (b'name', ), b'data')],
1616
 
                         list(index.iter_all_entries()))
 
1568
        index = self.make_index(nodes=[(('name', ), 'data')])
 
1569
        self.assertEqual([(index, ('name', ), 'data')],
 
1570
            list(index.iter_all_entries()))
1617
1571
 
1618
1572
    def test_iter_all_entries_references(self):
1619
1573
        index = self.make_index(1, nodes=[
1620
 
            ((b'name', ), b'data', ([(b'ref', )], )),
1621
 
            ((b'ref', ), b'refdata', ([], ))])
1622
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref', ),),)),
1623
 
                          (index, (b'ref', ), b'refdata', ((), ))},
1624
 
                         set(index.iter_all_entries()))
 
1574
            (('name', ), 'data', ([('ref', )], )),
 
1575
            (('ref', ), 'refdata', ([], ))])
 
1576
        self.assertEqual({(index, ('name', ), 'data', ((('ref', ),),)),
 
1577
            (index, ('ref', ), 'refdata', ((), ))},
 
1578
            set(index.iter_all_entries()))
1625
1579
 
1626
1580
    def test_iteration_absent_skipped(self):
1627
1581
        index = self.make_index(1, nodes=[
1628
 
            ((b'name', ), b'data', ([(b'ref', )], ))])
1629
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
1630
 
                         set(index.iter_all_entries()))
1631
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
1632
 
                         set(index.iter_entries([(b'name', )])))
1633
 
        self.assertEqual([], list(index.iter_entries([(b'ref', )])))
 
1582
            (('name', ), 'data', ([('ref', )], ))])
 
1583
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),))},
 
1584
            set(index.iter_all_entries()))
 
1585
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),))},
 
1586
            set(index.iter_entries([('name', )])))
 
1587
        self.assertEqual([], list(index.iter_entries([('ref', )])))
1634
1588
 
1635
1589
    def test_iter_all_keys(self):
1636
1590
        index = self.make_index(1, nodes=[
1637
 
            ((b'name', ), b'data', ([(b'ref', )], )),
1638
 
            ((b'ref', ), b'refdata', ([], ))])
1639
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
1640
 
                          (index, (b'ref', ), b'refdata', ((), ))},
1641
 
                         set(index.iter_entries([(b'name', ), (b'ref', )])))
 
1591
            (('name', ), 'data', ([('ref', )], )),
 
1592
            (('ref', ), 'refdata', ([], ))])
 
1593
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
 
1594
            (index, ('ref', ), 'refdata', ((), ))},
 
1595
            set(index.iter_entries([('name', ), ('ref', )])))
1642
1596
 
1643
1597
    def test_iter_key_prefix_1_key_element_no_refs(self):
1644
 
        index = self.make_index(nodes=[
1645
 
            ((b'name', ), b'data'),
1646
 
            ((b'ref', ), b'refdata')])
1647
 
        self.assertEqual({(index, (b'name', ), b'data'),
1648
 
                          (index, (b'ref', ), b'refdata')},
1649
 
                         set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
 
1598
        index = self.make_index( nodes=[
 
1599
            (('name', ), 'data'),
 
1600
            (('ref', ), 'refdata')])
 
1601
        self.assertEqual({(index, ('name', ), 'data'),
 
1602
            (index, ('ref', ), 'refdata')},
 
1603
            set(index.iter_entries_prefix([('name', ), ('ref', )])))
1650
1604
 
1651
1605
    def test_iter_key_prefix_1_key_element_refs(self):
1652
1606
        index = self.make_index(1, nodes=[
1653
 
            ((b'name', ), b'data', ([(b'ref', )], )),
1654
 
            ((b'ref', ), b'refdata', ([], ))])
1655
 
        self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
1656
 
                          (index, (b'ref', ), b'refdata', ((), ))},
1657
 
                         set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
 
1607
            (('name', ), 'data', ([('ref', )], )),
 
1608
            (('ref', ), 'refdata', ([], ))])
 
1609
        self.assertEqual({(index, ('name', ), 'data', ((('ref',),),)),
 
1610
            (index, ('ref', ), 'refdata', ((), ))},
 
1611
            set(index.iter_entries_prefix([('name', ), ('ref', )])))
1658
1612
 
1659
1613
    def test_iter_key_prefix_2_key_element_no_refs(self):
1660
1614
        index = self.make_index(key_elements=2, nodes=[
1661
 
            ((b'name', b'fin1'), b'data'),
1662
 
            ((b'name', b'fin2'), b'beta'),
1663
 
            ((b'ref', b'erence'), b'refdata')])
1664
 
        self.assertEqual({(index, (b'name', b'fin1'), b'data'),
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'),
1668
 
                          (index, (b'name', b'fin2'), b'beta')},
1669
 
                         set(index.iter_entries_prefix([(b'name', None)])))
 
1615
            (('name', 'fin1'), 'data'),
 
1616
            (('name', 'fin2'), 'beta'),
 
1617
            (('ref', 'erence'), 'refdata')])
 
1618
        self.assertEqual({(index, ('name', 'fin1'), 'data'),
 
1619
            (index, ('ref', 'erence'), 'refdata')},
 
1620
            set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
 
1621
        self.assertEqual({(index, ('name', 'fin1'), 'data'),
 
1622
            (index, ('name', 'fin2'), 'beta')},
 
1623
            set(index.iter_entries_prefix([('name', None)])))
1670
1624
 
1671
1625
    def test_iter_key_prefix_2_key_element_refs(self):
1672
1626
        index = self.make_index(1, key_elements=2, nodes=[
1673
 
            ((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], )),
1674
 
            ((b'name', b'fin2'), b'beta', ([], )),
1675
 
            ((b'ref', b'erence'), b'refdata', ([], ))])
1676
 
        self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
1677
 
                          (index, (b'ref', b'erence'), b'refdata', ((), ))},
1678
 
                         set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
1679
 
        self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
1680
 
                          (index, (b'name', b'fin2'), b'beta', ((), ))},
1681
 
                         set(index.iter_entries_prefix([(b'name', None)])))
 
1627
            (('name', 'fin1'), 'data', ([('ref', 'erence')], )),
 
1628
            (('name', 'fin2'), 'beta', ([], )),
 
1629
            (('ref', 'erence'), 'refdata', ([], ))])
 
1630
        self.assertEqual({(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
 
1631
            (index, ('ref', 'erence'), 'refdata', ((), ))},
 
1632
            set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
 
1633
        self.assertEqual({(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
 
1634
            (index, ('name', 'fin2'), 'beta', ((), ))},
 
1635
            set(index.iter_entries_prefix([('name', None)])))
1682
1636
 
1683
1637
    def test_iter_nothing_empty(self):
1684
1638
        index = self.make_index()
1686
1640
 
1687
1641
    def test_iter_missing_entry_empty(self):
1688
1642
        index = self.make_index()
1689
 
        self.assertEqual([], list(index.iter_entries([b'a'])))
 
1643
        self.assertEqual([], list(index.iter_entries(['a'])))
1690
1644
 
1691
1645
    def test_key_count_empty(self):
1692
1646
        index = self.make_index()
1693
1647
        self.assertEqual(0, index.key_count())
1694
1648
 
1695
1649
    def test_key_count_one(self):
1696
 
        index = self.make_index(nodes=[((b'name', ), b'')])
 
1650
        index = self.make_index(nodes=[(('name', ), '')])
1697
1651
        self.assertEqual(1, index.key_count())
1698
1652
 
1699
1653
    def test_key_count_two(self):
1700
 
        index = self.make_index(nodes=[((b'name', ), b''), ((b'foo', ), b'')])
 
1654
        index = self.make_index(nodes=[(('name', ), ''), (('foo', ), '')])
1701
1655
        self.assertEqual(2, index.key_count())
1702
1656
 
1703
1657
    def test_validate_empty(self):
1705
1659
        index.validate()
1706
1660
 
1707
1661
    def test_validate_no_refs_content(self):
1708
 
        index = self.make_index(nodes=[((b'key', ), b'value')])
 
1662
        index = self.make_index(nodes=[(('key', ), 'value')])
1709
1663
        index.validate()
1710
1664
 
1711
1665
 
1713
1667
 
1714
1668
    def make_index(self, ref_lists=1, key_elements=2, nodes=[],
1715
1669
                   add_callback=False):
1716
 
        result = _mod_index.InMemoryGraphIndex(
1717
 
            ref_lists, key_elements=key_elements)
 
1670
        result = index.InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1718
1671
        result.add_nodes(nodes)
1719
1672
        if add_callback:
1720
1673
            add_nodes_callback = result.add_nodes
1721
1674
        else:
1722
1675
            add_nodes_callback = None
1723
 
        adapter = _mod_index.GraphIndexPrefixAdapter(
1724
 
            result, (b'prefix', ), key_elements - 1,
 
1676
        adapter = index.GraphIndexPrefixAdapter(
 
1677
            result, ('prefix', ), key_elements - 1,
1725
1678
            add_nodes_callback=add_nodes_callback)
1726
1679
        return result, adapter
1727
1680
 
1728
1681
    def test_add_node(self):
1729
1682
        index, adapter = self.make_index(add_callback=True)
1730
 
        adapter.add_node((b'key',), b'value', (((b'ref',),),))
1731
 
        self.assertEqual({(index, (b'prefix', b'key'), b'value',
1732
 
                           (((b'prefix', b'ref'),),))},
1733
 
                         set(index.iter_all_entries()))
 
1683
        adapter.add_node(('key',), 'value', ((('ref',),),))
 
1684
        self.assertEqual({(index, ('prefix', 'key'), 'value',
 
1685
                               ((('prefix', 'ref'),),))},
 
1686
            set(index.iter_all_entries()))
1734
1687
 
1735
1688
    def test_add_nodes(self):
1736
1689
        index, adapter = self.make_index(add_callback=True)
1737
1690
        adapter.add_nodes((
1738
 
            ((b'key',), b'value', (((b'ref',),),)),
1739
 
            ((b'key2',), b'value2', ((),)),
 
1691
            (('key',), 'value', ((('ref',),),)),
 
1692
            (('key2',), 'value2', ((),)),
1740
1693
            ))
1741
1694
        self.assertEqual({
1742
 
            (index, (b'prefix', b'key2'), b'value2', ((),)),
1743
 
            (index, (b'prefix', b'key'), b'value', (((b'prefix', b'ref'),),))
 
1695
            (index, ('prefix', 'key2'), 'value2', ((),)),
 
1696
            (index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))
1744
1697
            },
1745
1698
            set(index.iter_all_entries()))
1746
1699
 
1747
1700
    def test_construct(self):
1748
 
        idx = _mod_index.InMemoryGraphIndex()
1749
 
        adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1)
 
1701
        idx = index.InMemoryGraphIndex()
 
1702
        adapter = index.GraphIndexPrefixAdapter(idx, ('prefix', ), 1)
1750
1703
 
1751
1704
    def test_construct_with_callback(self):
1752
 
        idx = _mod_index.InMemoryGraphIndex()
1753
 
        adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1,
1754
 
                                                     idx.add_nodes)
 
1705
        idx = index.InMemoryGraphIndex()
 
1706
        adapter = index.GraphIndexPrefixAdapter(idx, ('prefix', ), 1,
 
1707
                                                idx.add_nodes)
1755
1708
 
1756
1709
    def test_iter_all_entries_cross_prefix_map_errors(self):
1757
1710
        index, adapter = self.make_index(nodes=[
1758
 
            ((b'prefix', b'key1'), b'data1', (((b'prefixaltered', b'key2'),),))])
1759
 
        self.assertRaises(_mod_index.BadIndexData, list,
1760
 
                          adapter.iter_all_entries())
 
1711
            (('prefix', 'key1'), 'data1', ((('prefixaltered', 'key2'),),))])
 
1712
        self.assertRaises(errors.BadIndexData, list, adapter.iter_all_entries())
1761
1713
 
1762
1714
    def test_iter_all_entries(self):
1763
1715
        index, adapter = self.make_index(nodes=[
1764
 
            ((b'notprefix', b'key1'), b'data', ((), )),
1765
 
            ((b'prefix', b'key1'), b'data1', ((), )),
1766
 
            ((b'prefix', b'key2'), b'data2', (((b'prefix', b'key1'),),))])
1767
 
        self.assertEqual({(index, (b'key1', ), b'data1', ((),)),
1768
 
                          (index, (b'key2', ), b'data2', (((b'key1',),),))},
1769
 
                         set(adapter.iter_all_entries()))
 
1716
            (('notprefix', 'key1'), 'data', ((), )),
 
1717
            (('prefix', 'key1'), 'data1', ((), )),
 
1718
            (('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
 
1719
        self.assertEqual({(index, ('key1', ), 'data1', ((),)),
 
1720
            (index, ('key2', ), 'data2', ((('key1',),),))},
 
1721
            set(adapter.iter_all_entries()))
1770
1722
 
1771
1723
    def test_iter_entries(self):
1772
1724
        index, adapter = self.make_index(nodes=[
1773
 
            ((b'notprefix', b'key1'), b'data', ((), )),
1774
 
            ((b'prefix', b'key1'), b'data1', ((), )),
1775
 
            ((b'prefix', b'key2'), b'data2', (((b'prefix', b'key1'),),))])
 
1725
            (('notprefix', 'key1'), 'data', ((), )),
 
1726
            (('prefix', 'key1'), 'data1', ((), )),
 
1727
            (('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1776
1728
        # ask for many - get all
1777
 
        self.assertEqual({(index, (b'key1', ), b'data1', ((),)),
1778
 
                          (index, (b'key2', ), b'data2', (((b'key1', ),),))},
1779
 
                         set(adapter.iter_entries([(b'key1', ), (b'key2', )])))
 
1729
        self.assertEqual({(index, ('key1', ), 'data1', ((),)),
 
1730
            (index, ('key2', ), 'data2', ((('key1', ),),))},
 
1731
            set(adapter.iter_entries([('key1', ), ('key2', )])))
1780
1732
        # ask for one, get one
1781
 
        self.assertEqual({(index, (b'key1', ), b'data1', ((),))},
1782
 
                         set(adapter.iter_entries([(b'key1', )])))
 
1733
        self.assertEqual({(index, ('key1', ), 'data1', ((),))},
 
1734
            set(adapter.iter_entries([('key1', )])))
1783
1735
        # ask for missing, get none
1784
1736
        self.assertEqual(set(),
1785
 
                         set(adapter.iter_entries([(b'key3', )])))
 
1737
            set(adapter.iter_entries([('key3', )])))
1786
1738
 
1787
1739
    def test_iter_entries_prefix(self):
1788
1740
        index, adapter = self.make_index(key_elements=3, nodes=[
1789
 
            ((b'notprefix', b'foo', b'key1'), b'data', ((), )),
1790
 
            ((b'prefix', b'prefix2', b'key1'), b'data1', ((), )),
1791
 
            ((b'prefix', b'prefix2', b'key2'), b'data2', (((b'prefix', b'prefix2', b'key1'),),))])
 
1741
            (('notprefix', 'foo', 'key1'), 'data', ((), )),
 
1742
            (('prefix', 'prefix2', 'key1'), 'data1', ((), )),
 
1743
            (('prefix', 'prefix2', 'key2'), 'data2', ((('prefix', 'prefix2', 'key1'),),))])
1792
1744
        # ask for a prefix, get the results for just that prefix, adjusted.
1793
 
        self.assertEqual({(index, (b'prefix2', b'key1', ), b'data1', ((),)),
1794
 
                          (index, (b'prefix2', b'key2', ), b'data2', (((b'prefix2', b'key1', ),),))},
1795
 
                         set(adapter.iter_entries_prefix([(b'prefix2', None)])))
 
1745
        self.assertEqual({(index, ('prefix2', 'key1', ), 'data1', ((),)),
 
1746
            (index, ('prefix2', 'key2', ), 'data2', ((('prefix2', 'key1', ),),))},
 
1747
            set(adapter.iter_entries_prefix([('prefix2', None)])))
1796
1748
 
1797
1749
    def test_key_count_no_matching_keys(self):
1798
1750
        index, adapter = self.make_index(nodes=[
1799
 
            ((b'notprefix', b'key1'), b'data', ((), ))])
 
1751
            (('notprefix', 'key1'), 'data', ((), ))])
1800
1752
        self.assertEqual(0, adapter.key_count())
1801
1753
 
1802
1754
    def test_key_count_some_keys(self):
1803
1755
        index, adapter = self.make_index(nodes=[
1804
 
            ((b'notprefix', b'key1'), b'data', ((), )),
1805
 
            ((b'prefix', b'key1'), b'data1', ((), )),
1806
 
            ((b'prefix', b'key2'), b'data2', (((b'prefix', b'key1'),),))])
 
1756
            (('notprefix', 'key1'), 'data', ((), )),
 
1757
            (('prefix', 'key1'), 'data1', ((), )),
 
1758
            (('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1807
1759
        self.assertEqual(2, adapter.key_count())
1808
1760
 
1809
1761
    def test_validate(self):
1810
1762
        index, adapter = self.make_index()
1811
1763
        calls = []
1812
 
 
1813
1764
        def validate():
1814
1765
            calls.append('called')
1815
1766
        index.validate = validate