Add test for unaligned hasher states
authorJakob Cornell <jakob+gpg@jcornell.net>
Sun, 28 Nov 2021 00:26:17 +0000 (18:26 -0600)
committerJakob Cornell <jakob+gpg@jcornell.net>
Sun, 28 Nov 2021 00:26:17 +0000 (18:26 -0600)
src/disk_jumble/tests/test_verify.py

index 1edc3cc14c0361090705ecadcca51304d9f2d36c..eea5007fa6cdf4500db396636b877ff73e6f8ce7 100644 (file)
@@ -174,7 +174,7 @@ class Tests(unittest.TestCase):
                                cursor.execute("select hasher_state from diskjumble.verify_piece_incomplete;")
                                self.assertEqual(cursor.fetchall(), [(hasher.ctx.serialize(),)])
 
-       def test_ignore_hasher_state(self):
+       def test_ignore_hasher_beginning_on_disk(self):
                """
                Test a run where a saved hasher state is available for use but isn't used due to the beginning of the piece
                being on disk.
@@ -213,6 +213,57 @@ class Tests(unittest.TestCase):
                                cursor.execute("select disk_id, disk_sectors from diskjumble.verify_pass;")
                                self.assertEqual(cursor.fetchall(), [(disk.id, NumericRange(0, disk.sector_count))])
 
+       def test_ignore_hasher_unaligned(self):
+               """
+               Test a run where a saved hasher isn't used because its entity data offset isn't sector-aligned on the target
+               disk.
+
+                           0   16  32  48  64  80  96  112 128
+               pieces:     [-------------- 0 -------------]
+               other disk: [--][--][--][--][--]
+               disk:                       [------][------]
+               """
+               piece_size = 128
+
+               other_disk = self._write_disk(16, 5)
+               disk = self._write_disk(32, 2)
+               with _random_file(piece_size, Random(0), on_disk = False) as torrent_file:
+                       torrent = _Torrent(torrent_file, piece_size)
+                       self._write_torrent(torrent)
+                       with self._conn.cursor() as cursor:
+                               cursor.executemany(
+                                       "insert into diskjumble.slab values (default, %s, %s, %s, %s, null);",
+                                       [
+                                               (other_disk.id, NumericRange(0, 5), torrent.info_hash, 0),
+                                               (disk.id, NumericRange(0, 2), torrent.info_hash, 64),
+                                       ]
+                               )
+
+                               do_verify(self._conn, other_disk.id, torrent_file, read_size = 16, read_tries = 1)
+                               cursor.execute("select count(*) from diskjumble.verify_piece_incomplete;")
+                               [(row_count,)] = cursor.fetchall()
+                               self.assertEqual(row_count, 1)
+
+                               disk_file = io.BytesIO(torrent_file.getvalue()[64:])
+                               do_verify(self._conn, disk.id, disk_file, read_size = 16, read_tries = 1)
+
+                               cursor.execute("""
+                                       select disk_id, disk_sectors
+                                       from diskjumble.verify_piece_incomplete natural join diskjumble.verify_piece_content;
+                               """)
+                               self.assertEqual(
+                                       cursor.fetchall(),
+                                       [(other_disk.id, NumericRange(0, 5))]
+                               )
+
+                               cursor.execute("select count(*) from diskjumble.verify_pass;")
+                               [(row_count,)] = cursor.fetchall()
+                               self.assertEqual(row_count, 0)
+
+                               cursor.execute("select count(*) from diskjumble.verify_piece_fail;")
+                               [(row_count,)] = cursor.fetchall()
+                               self.assertEqual(row_count, 0)
+
        def test_transient_read_errors(self):
                """
                Test a run where a read to the disk fails but fewer times than needed to mark the sector bad.