Skip to content

testing

Peterson Fernandes edited this page Aug 19, 2026 · 1 revision

Testing

CHDSharp ships a 558-test xUnit suite plus a deterministic 30-file corpus covering every format version, codec, map type, and parent/child combination. Tests run on net8.0, net9.0, and net10.0.


Test tiers

Tier Project Description
Unit CHDSharpTest Header/API tests, checksum test vectors, TOC parsing edge cases, error mapping, bounds validation, Huffman/FLAC/LZMA primitives, extraction, metadata, parity features.
Corpus CHDSharpTest Runs CheckFile (deep) and ReadHunk against 30 deterministic CHD fixtures in TestData/, driven by manifest.json (expected version, parent links, expected pass/fail).
Integration CHDSharpTest End-to-end CLI tests (CliIntegrationTests): directory scan, --random, --list, --parent.
Interactive CHDSharpTester WPF app that batch-verifies folders and cross-checks against chdman (header info, deep verify, SHA1, random-access extraction, codec decode, parent chains).
Encoder unit CHDSharpEncoderTest Tests for the CHDSharpEncoder creation library: endian/CRC/SHA1/deflate primitives, Huffman + V5 map compression, header, CUE/GDI/ISO/TOC parsers, metadata writer, per-hunk ratio logging.
Encoder validation CHDSharpEncoderTest Cross-validation of encoder output against chdman.exe v0.288 (info, verify, extractraw, createcd, createraw) and the CHDSharpLib reader — including 100 MB+ raw/CD round-trips and byte-for-byte file comparison with chdman createraw.

Test classes

Class Covers
HeaderAndApiTests Magic/version detection, CheckHeader, IsChdFile, open/read error paths
ReadHeaderTests Chd.ReadHeader/ReadHeaderAsync full header DTO (libchdr chd_read_header parity): all versions, field parity with an opened ChdFile, codec slots, child/parent hashes, V1 geometry, error paths, stream leave-open, async
ProgressReportingTests IProgress<ChdProgress> on CheckFile, CheckFileWithParent, ReadAllBytes, EnumerateHunks, ExtractToDirectory: per-hunk report counts, monotonicity, final totals, ordered parallel reports, backward-compatible defaults
CancellationTokenTests CancellationToken on all public APIs: pre-cancelled throws for Open/Read/ReadHunk/ReadAllBytes/ExtractToDirectory/CheckFile/CheckFileWithParent, cancelled-task async twins, mid-run cancellation of the parallel pipeline, OCE never swallowed by extraction
ChecksumTests CRC-32 / CRC-16 test vectors
CdRomAddressTests CdRomAddress MSF↔LBA conversion: BCD vectors, lead-in boundaries, 99-minute BCD limit, invalid-BCD throws, round trips
ReadSectorTests ReadSector/ReadSectorMsf/ReadFrame against the CD corpus (V3/V4/V5, cdlz/cdfl): sector/frame reads match the decompressed image, all-frames concatenation equals the whole image, MSF↔LBA equivalence, buffer/range error paths, non-CD rejection
TrackInfoTests / TrackInfoEdgeCaseTests TOC parsing across CHTR, CHT2, CHCD, CHGD, CHGT; GD-ROM pad frames; binary track parsing
CorpusTests Deep verification + open/read on all 30 fixtures
SecondCompressedTests V3/V4 ZLIB_PLUS secondary-codec hunks
ExtractTests / TrackInfoTests Extraction, CUE/GDI generation, reporting
ParityFeaturesTests GetMetadata, Precache, V1/V2 synthesized GDDD, OpenAsync overloads
LargeFileTests Synthetic uncompressed V5 CHD with a 20 GiB declared image: open, random access past 4 GiB (stored hunk + zero hunks), ReadAllBytes 2 GiB guard. Verifies libchdr #147 (sources > 10 GB).
LruCacheTests ChdFile.CacheSize / ConfigureCache multi-hunk LRU cache (libchdr #36): default size, lower-bounding, cross-hunk correctness, eviction/promotion, cache reconfiguration, parent-referenced hunk caching.
ChdApiTests, ChdFileTests, ChdTocParserTests, ChdCommonTests, ModelTests, UtilityTests, BigEndianTests, BoundsValidationTests, ExceptionHandlingTests, HuffmanDecoderTests, EccVerifyTests, CliAdditionalTests Remaining units

The corpus

CHDSharpTest/TestData/ contains 30 CHD files generated by CHDSharpTestGen:

Version Files Coverage
V1 1 zlib (legacy hdcomp)
V2 1 zlib (synthesized V1→V2)
V3 4 zlib, CD, A/V laserdisc, parent chain
V4 5 zlib, uncompressed, CD, A/V laserdisc, parent chain
V5 19 zlib, lzma, huff, flac, zstd, multi-codec, uncompressed, tiny (expected failure), odd-size, parent, compressed-map child, uncompressed-map child, unaligned-hunk child, CD cdzl/cdlz/cdfl/cdzs/default, laserdisc avhuff (mono + stereo)

manifest.json drives the corpus tests: each entry declares the expected version, optional parent file, and whether the fixture is expected to verify ("ok") or fail ("invalid").

The stereo AVHuff fixture (v5_av_stereo.chd) is a regression test for the laserdisc extraction bug — it fails to decompress with any decoder configured with the wrong (non-mono) FLAC channel count.


Running the tests

# Everything (all target frameworks)
dotnet test

# One framework
dotnet test -f net10.0

# One class / filter
dotnet test --filter "FullyQualifiedName~CorpusTests"
dotnet test --filter "FullyQualifiedName~ParityFeatures"

# Detailed console output
dotnet test -v detailed

# The encoder suite only (CHDSharpEncoderTest; requires chdman.exe next to the test assembly)
dotnet test CHDSharpEncoderTest/
dotnet test CHDSharpEncoderTest/ --filter "FullyQualifiedName~LargeFileValidationTests"

The encoder validation tests use chdman.exe (MAME 0.288), resolved from the test output directory or CHDSharpTester/; if it is unavailable those tests skip.

Regenerating the corpus

CHDSharpTestGen builds source images deterministically (seeded PRNG) and drives vintage chdman/hdcomp binaries to produce the fixtures — regenerating yields byte-identical files.

# Prerequisites: chdman binaries in CHDSharpTest/chdman/:
#   hdcomp_v1.exe  (~MAME 0.77,   V1)
#   chdman_v3.exe  (~MAME 0.130,  V3)
#   chdman_v4.exe  (~MAME 0.145,  V4)
#   chdman_v5.exe  (MAME 0.288,   V5)

dotnet run --project CHDSharpTestGen

Extra generator flags: --avitest (AVI passthrough test), --hunkdebug <file> (inspect a single FLAC-hunked V5 CHD).


The WPF tester (CHDSharpTester)

An interactive tool that:

  • batch-verifies directories of CHDs with the same logic as chdman verify,
  • displays header info, compression breakdown, SHA1/MD5, and per-codec stats,
  • performs random-access extraction and compares against chdman extractraw,
  • exercises parent/child chains.
dotnet run --project CHDSharpTester

It requires the chdman binaries in CHDSharpTest/chdman/ for cross-checks.


Golden rules for contributors

  1. Every new feature needs a test — corpus fixture for format-level behavior, unit test for API-level behavior.
  2. Corpus fixtures must be deterministic — regenerate via CHDSharpTestGen, never hand-edit binaries.
  3. New fixtures must be registered in manifest.json with the correct expected version and pass/fail status.
  4. All 468 tests must pass on all three TFMs before merging.

Clone this wiki locally