1233
1233
bytes = reader_callable(length)
1234
1234
self.assertRecordContentEqual(k1, version_id, bytes)
1236
# permutations left to test:
1236
# permutations left to explicitly test:
1237
1237
# * getting a version where all its parents are ghosts
1238
1238
# * reader_func edge-cases:
1239
1239
# * read too little
1240
1240
# * read too much
1241
1241
# * multiple read calls
1243
# * reading records with other data interspersed skips interspersed data.
1244
# insert [A [], B [A], C [A]], read [A, C].
1245
1248
# * move callable into own class (see XXX in get_data_stream)
1246
1249
# * insert data stream into knits
1251
def assertKnitFilesEqual(self, knit1, knit2):
1252
"""Assert that the contents of the index and data files of two knits are
1256
knit1.transport.get_bytes(knit1._data._filename),
1257
knit2.transport.get_bytes(knit2._data._filename))
1259
knit1.transport.get_bytes(knit1._index._filename),
1260
knit2.transport.get_bytes(knit2._index._filename))
1262
def test_insert_data_stream_empty(self):
1263
"""Inserting a data stream with no records should not put any data into
1266
k1 = self.make_test_knit()
1267
k1.insert_data_stream(
1268
(k1.get_format_signature(), [], lambda ignored: ''))
1269
self.assertEqual('', k1.transport.get_bytes(k1._data._filename),
1270
"The .knit should be completely empty.")
1271
self.assertEqual(k1._index.HEADER,
1272
k1.transport.get_bytes(k1._index._filename),
1273
"The .kndx should have nothing apart from the header.")
1275
def test_insert_data_stream_one_record(self):
1276
"""Inserting a data stream with one record from a knit with one record
1277
results in byte-identical files.
1279
source = self.make_test_knit(name='source')
1280
source.add_lines('text-a', [], split_lines(TEXT_1))
1281
data_stream = source.get_data_stream(['text-a'])
1283
target = self.make_test_knit(name='target')
1284
target.insert_data_stream(data_stream)
1286
self.assertKnitFilesEqual(source, target)
1288
def test_insert_data_stream_records_already_present(self):
1289
"""Insert a data stream where some records are alreday present in the
1290
target, and some not. Only the new records are inserted.
1292
source = self.make_test_knit(name='source')
1293
target = self.make_test_knit(name='target')
1294
# Insert 'text-a' into both source and target
1295
source.add_lines('text-a', [], split_lines(TEXT_1))
1296
target.insert_data_stream(source.get_data_stream(['text-a']))
1297
# Insert 'text-b' into just the source.
1298
source.add_lines('text-b', ['text-a'], split_lines(TEXT_1))
1299
# Get a data stream of both text-a and text-b, and insert it.
1300
data_stream = source.get_data_stream(['text-a', 'text-b'])
1301
target.insert_data_stream(data_stream)
1302
# The source and target will now be identical. This means the text-a
1303
# record was not added a second time.
1304
self.assertKnitFilesEqual(source, target)
1306
def test_insert_data_stream_multiple_records(self):
1307
"""Inserting a data stream of all records from a knit with multiple
1308
records results in byte-identical files.
1310
source = self.make_test_knit(name='source')
1311
source.add_lines('text-a', [], split_lines(TEXT_1))
1312
source.add_lines('text-b', ['text-a'], split_lines(TEXT_1))
1313
source.add_lines('text-c', [], split_lines(TEXT_1))
1314
data_stream = source.get_data_stream(['text-a', 'text-b', 'text-c'])
1316
target = self.make_test_knit(name='target')
1317
target.insert_data_stream(data_stream)
1319
self.assertKnitFilesEqual(source, target)
1321
def test_insert_data_stream_ghost_parent(self):
1322
"""Insert a data stream with a record that has a ghost parent."""
1323
# Make a knit with a record, text-a, that has a ghost parent.
1324
source = self.make_test_knit(name='source')
1325
source.add_lines_with_ghosts('text-a', ['text-ghost'],
1326
split_lines(TEXT_1))
1327
data_stream = source.get_data_stream(['text-a'])
1329
target = self.make_test_knit(name='target')
1330
target.insert_data_stream(data_stream)
1332
self.assertKnitFilesEqual(source, target)
1334
# The target knit object is in a consistent state, i.e. the record we
1335
# just added is immediately visible.
1336
self.assertTrue(target.has_version('text-a'))
1337
self.assertTrue(target.has_ghost('text-ghost'))
1338
self.assertEqual(split_lines(TEXT_1), target.get_lines('text-a'))
1340
def test_insert_data_stream_inconsistent_version_lines(self):
1341
"""Inserting a data stream which has different content for a version_id
1342
than already exists in the knit will raise KnitCorrupt.
1344
source = self.make_test_knit(name='source')
1345
target = self.make_test_knit(name='target')
1346
# Insert a different 'text-a' into both source and target
1347
source.add_lines('text-a', [], split_lines(TEXT_1))
1348
target.add_lines('text-a', [], split_lines(TEXT_2))
1349
# Insert a data stream with conflicting content into the target
1350
data_stream = source.get_data_stream(['text-a'])
1352
errors.KnitCorrupt, target.insert_data_stream, data_stream)
1354
def test_insert_data_stream_inconsistent_version_parents(self):
1355
"""Inserting a data stream which has different parents for a version_id
1356
than already exists in the knit will raise KnitCorrupt.
1358
source = self.make_test_knit(name='source')
1359
target = self.make_test_knit(name='target')
1360
# Insert a different 'text-a' into both source and target. They differ
1361
# only by the parents list, the content is the same.
1362
source.add_lines_with_ghosts('text-a', [], split_lines(TEXT_1))
1363
target.add_lines_with_ghosts('text-a', ['a-ghost'], split_lines(TEXT_1))
1364
# Insert a data stream with conflicting content into the target
1365
data_stream = source.get_data_stream(['text-a'])
1367
errors.KnitCorrupt, target.insert_data_stream, data_stream)
1369
def test_insert_data_stream_incompatible_format(self):
1370
"""A data stream in a different format to the target knit cannot be
1373
It will raise KnitDataStreamIncompatible.
1375
data_stream = ('fake-format-signature', [], lambda _: '')
1376
target = self.make_test_knit(name='target')
1378
errors.KnitDataStreamIncompatible,
1379
target.insert_data_stream, data_stream)
1250
1383
Banana cup cakes: