From d036b284ef2f547960b5ddef99fe571a0db3afee Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 8 Oct 2026 18:52:10 +0100 Subject: [PATCH] Add a test recovering a damaged tracks block with erasure coding when opening --- tests/erasure_coding.cpp | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tests/erasure_coding.cpp b/tests/erasure_coding.cpp index 8d6f79a..84e0526 100644 --- a/tests/erasure_coding.cpp +++ b/tests/erasure_coding.cpp @@ -401,3 +401,74 @@ TEST_F(ErasureCodingTest, CDSectorSizeImage) ASSERT_TRUE(success) << "Failed to read all sectors from CD EC image"; EXPECT_EQ(read_crc, golden_crc) << "CRC mismatch on CD EC image"; } + +/** + * @test Damage the tracks block of an erasure coded CD image: opening it must recover the tracks, which needs the + * erasure coding map loaded before the indexed blocks are processed. + */ +TEST_F(ErasureCodingTest, RecoverCorruptedTracksBlockOnOpen) +{ + const char *kFilename = "ec_tracks_output.aif"; + + void *ctx = aaruf_create(kFilename, 15 /* CD-ROM */, 2048, 64, 0, 0, "deduplicate=false;compress=false", + (const uint8_t *)"gtest_ec", 8, 0, 1, false); + ASSERT_NE(ctx, nullptr); + ASSERT_EQ(aaruf_set_erasure_coding(ctx, 1 /* RS-Vandermonde */, 4, 2), AARUF_STATUS_OK); + + TrackEntry track{}; + track.sequence = 1; + track.type = kTrackTypeCdMode1; + track.start = 0; + track.end = 63; + track.session = 1; + track.flags = 0x04; + ASSERT_EQ(aaruf_set_tracks(ctx, &track, 1), AARUF_STATUS_OK); + + uint8_t sector[2048]; + + for(uint64_t i = 0; i < 64; i++) + { + memset(sector, (int)i, sizeof(sector)); + ASSERT_EQ(aaruf_write_sector(ctx, i, false, sector, SectorStatusDumped, sizeof(sector)), AARUF_STATUS_OK); + } + + ASSERT_EQ(aaruf_close(ctx), AARUF_STATUS_OK); + + // Find the tracks block + ctx = aaruf_open(kFilename, false, nullptr); + ASSERT_NE(ctx, nullptr); + uint64_t offset = 0; + { + const auto *actx = static_cast(ctx); + + for(unsigned int i = 0; i < utarray_len(actx->index_entries); i++) + { + const auto *entry = static_cast(utarray_eltptr(actx->index_entries, i)); + if(entry->blockType == TracksBlock) offset = entry->offset; + } + } + EXPECT_EQ(aaruf_close(ctx), AARUF_STATUS_OK); + ASSERT_NE(offset, 0U); + + // Damage a track entry, so its CRC fails + FILE *file = fopen(kFilename, "r+b"); + ASSERT_NE(file, nullptr); + ASSERT_EQ(fseek(file, (long)(offset + sizeof(TracksHeader) + 2), SEEK_SET), 0); + const int byte = fgetc(file); + ASSERT_NE(byte, EOF); + ASSERT_EQ(fseek(file, (long)(offset + sizeof(TracksHeader) + 2), SEEK_SET), 0); + fputc(byte ^ 0xFF, file); + fclose(file); + + ctx = aaruf_open(kFilename, false, nullptr); + ASSERT_NE(ctx, nullptr); + + TrackEntry read_track{}; + size_t length = sizeof(read_track); + EXPECT_EQ(aaruf_get_tracks(ctx, (uint8_t *)&read_track, &length), AARUF_STATUS_OK); + EXPECT_EQ(length, sizeof(TrackEntry)); + EXPECT_EQ(memcmp(&read_track, &track, sizeof(TrackEntry)), 0) << "the tracks must be recovered on open"; + + EXPECT_EQ(aaruf_close(ctx), AARUF_STATUS_OK); + remove(kFilename); +}