137
137
reader = self.get_reader_for("Bazaar pack format 1\nB5\n\naaaaaE")
138
138
expected_records = [([], 'aaaaa')]
139
self.assertEqual(expected_records, list(reader.iter_records()))
141
[(names, read_bytes(None))
142
for (names, read_bytes) in reader.iter_records()])
141
144
def test_validate_empty_container(self):
145
"""validate does not raise an error for a container with no records."""
142
146
reader = self.get_reader_for("Bazaar pack format 1\nE")
143
147
# No exception raised
144
148
reader.validate()
146
150
def test_validate_non_empty_valid_container(self):
151
"""validate does not raise an error for a container with a valid record.
147
153
reader = self.get_reader_for("Bazaar pack format 1\nB3\nname\n\nabcE")
148
154
# No exception raised
149
155
reader.validate()
151
157
def test_validate_bad_format(self):
158
"""validate raises an error for unrecognised format strings.
160
It may raise either UnexpectedEndOfContainerError or
161
UnknownContainerFormatError, depending on exactly what the string is.
152
163
inputs = ["", "x", "Bazaar pack format 1", "bad\n"]
153
164
for input in inputs:
154
165
reader = self.get_reader_for(input)
160
171
def test_validate_bad_record_marker(self):
172
"""validate raises UnknownRecordTypeError for unrecognised record
161
175
reader = self.get_reader_for("Bazaar pack format 1\nX")
162
176
self.assertRaises(errors.UnknownRecordTypeError, reader.validate)
164
178
def test_validate_data_after_end_marker(self):
179
"""validate raises ContainerHasExcessDataError if there are any bytes
180
after the end of the container.
165
182
reader = self.get_reader_for("Bazaar pack format 1\nEcrud")
166
183
self.assertRaises(
167
184
errors.ContainerHasExcessDataError, reader.validate)
169
186
def test_validate_no_end_marker(self):
187
"""validate raises UnexpectedEndOfContainerError if there's no end of
188
container marker, even if the container up to this point has been valid.
170
190
reader = self.get_reader_for("Bazaar pack format 1\n")
171
191
self.assertRaises(
172
192
errors.UnexpectedEndOfContainerError, reader.validate)
194
def test_validate_duplicate_name(self):
195
"""validate raises DuplicateRecordNameError if the same name occurs
196
multiple times in the container.
198
reader = self.get_reader_for(
199
"Bazaar pack format 1\n"
203
self.assertRaises(errors.DuplicateRecordNameError, reader.validate)
205
def test_validate_undecodeable_name(self):
206
"""Names that aren't valid UTF-8 cause validate to fail."""
207
reader = self.get_reader_for("Bazaar pack format 1\nB0\n\xcc\n\nE")
208
self.assertRaises(errors.InvalidRecordError, reader.validate)
175
211
class TestBytesRecordReader(tests.TestCase):
176
"""Tests for parsing Bytes records with BytesRecordReader."""
212
"""Tests for reading and validating Bytes records with BytesRecordReader."""
178
214
def get_reader_for(self, bytes):
179
215
stream = StringIO(bytes)
187
223
reader = self.get_reader_for("5\n\naaaaa")
188
names, bytes = reader.read()
224
names, get_bytes = reader.read()
189
225
self.assertEqual([], names)
190
self.assertEqual('aaaaa', bytes)
226
self.assertEqual('aaaaa', get_bytes(None))
192
228
def test_record_with_one_name(self):
193
229
"""Reading a Bytes record with one name returns a list of just that
196
232
reader = self.get_reader_for("5\nname1\n\naaaaa")
197
names, bytes = reader.read()
233
names, get_bytes = reader.read()
198
234
self.assertEqual(['name1'], names)
199
self.assertEqual('aaaaa', bytes)
235
self.assertEqual('aaaaa', get_bytes(None))
201
237
def test_record_with_two_names(self):
202
238
"""Reading a Bytes record with two names returns a list of both names.
204
240
reader = self.get_reader_for("5\nname1\nname2\n\naaaaa")
205
names, bytes = reader.read()
241
names, get_bytes = reader.read()
206
242
self.assertEqual(['name1', 'name2'], names)
207
self.assertEqual('aaaaa', bytes)
243
self.assertEqual('aaaaa', get_bytes(None))
209
245
def test_invalid_length(self):
210
246
"""If the length-prefix is not a number, parsing raises
226
262
complete_record = "6\nname\n\nabcdef"
227
263
for count in range(0, len(complete_record)):
228
reader = self.get_reader_for(complete_record[:count])
229
# We don't use assertRaises to make diagnosing failures easier.
264
incomplete_record = complete_record[:count]
265
reader = self.get_reader_for(incomplete_record)
266
# We don't use assertRaises to make diagnosing failures easier
267
# (assertRaises doesn't allow a custom failure message).
269
names, read_bytes = reader.read()
232
271
except errors.UnexpectedEndOfContainerError:
236
275
"UnexpectedEndOfContainerError not raised when parsing %r"
237
% (input.getvalue()))
276
% (incomplete_record,))
239
278
def test_initial_eof(self):
240
279
"""EOF before any bytes read at all."""
266
305
self.assertRaises(errors.InvalidRecordError, reader.read)
268
307
def test_validate_whitespace_in_name(self):
269
reader = self.get_reader_for("0\nbad name\n\nE")
308
"""Names must have no whitespace."""
309
reader = self.get_reader_for("0\nbad name\n\n")
270
310
self.assertRaises(errors.InvalidRecordError, reader.validate)
272
312
def test_validate_interrupted_prelude(self):
313
"""EOF during reading a record's prelude causes validate to fail."""
273
314
reader = self.get_reader_for("")
274
315
self.assertRaises(
275
316
errors.UnexpectedEndOfContainerError, reader.validate)
277
318
def test_validate_interrupted_body(self):
319
"""EOF during reading a record's body causes validate to fail."""
278
320
reader = self.get_reader_for("1\n\n")
279
321
self.assertRaises(
280
322
errors.UnexpectedEndOfContainerError, reader.validate)
282
324
def test_validate_unparseable_length(self):
325
"""An unparseable record length causes validate to fail."""
283
326
reader = self.get_reader_for("\n\n")
284
327
self.assertRaises(
285
328
errors.InvalidRecordError, reader.validate)
330
def test_validate_undecodeable_name(self):
331
"""Names that aren't valid UTF-8 cause validate to fail."""
332
reader = self.get_reader_for("0\n\xcc\n\n")
333
self.assertRaises(errors.InvalidRecordError, reader.validate)
335
def test_read_max_length(self):
336
"""If the max_length passed to the callable returned by read is not
337
None, then no more than that many bytes will be read.
339
reader = self.get_reader_for("6\n\nabcdef")
340
names, get_bytes = reader.read()
341
self.assertEqual('abc', get_bytes(3))
343
def test_read_no_max_length(self):
344
"""If the max_length passed to the callable returned by read is None,
345
then all the bytes in the record will be read.
347
reader = self.get_reader_for("6\n\nabcdef")
348
names, get_bytes = reader.read()
349
self.assertEqual('abcdef', get_bytes(None))
351
def test_repeated_read_calls(self):
352
"""Repeated calls to the callable returned from BytesRecordReader.read
353
will not read beyond the end of the record.
355
reader = self.get_reader_for("6\n\nabcdefB3\nnext-record\nXXX")
356
names, get_bytes = reader.read()
357
self.assertEqual('abcdef', get_bytes(None))
358
self.assertEqual('', get_bytes(None))
359
self.assertEqual('', get_bytes(99))