Skip to content

Latest commit

 

History

History
122 lines (100 loc) · 7.16 KB

File metadata and controls

122 lines (100 loc) · 7.16 KB

Testing

The test suite is split into two projects, so the default run is always the fast one:

  • RVZSharp.Tests313 synthetic tests (unit + end-to-end round trips), ~30 seconds per framework (net8.0, net9.0, net10.0). It is part of the solution.
  • RVZSharp.Slow.Tests97 real-file tests (full decode, structural checks, writer round trips against real game images), ~12 minutes when the games are mounted. It is deliberately kept out of the solution, so a plain dotnet test / solution run never executes it.
# fast suite (default; runs per target framework of the solution)
dotnet test CSharp_RVZSharp.sln -c Release

# a single class
dotnet test CSharp_RVZSharp.sln -c Release --filter "FullyQualifiedName~RvzWriterTests"

# slow / real-file suite (explicit opt-in; not part of the solution)
dotnet test RVZSharp.Slow.Tests -c Release

# a single framework (either project)
dotnet test RVZSharp.Slow.Tests -c Release --framework net8.0

Strategy

The suite runs against synthetic discs built in memory (cross-checked against the reference implementations' semantics) and, when a local library of real game images is mounted (F:\Nintendo GameCube, F:\Nintendo Wii), against real RVZ files validated byte-for-byte against their official No-Intro SHA-1s:

  1. Synthetic builders generate byte-exact images (RVZ/WIA, all legacy formats, and realistic Wii ISOs with tickets, partition tables and encrypted data).
  2. Round trips prove byte-exactness: build → write → read → compare.
  3. Format semantics were validated against Dolphin's C++ (References/dolphin-master) and the Go reader (References/rvz-1.0.3) — including a Python prototype used during development to pin down the PRNG seed-recovery algorithm before the C# port.
  4. Reference-alignment regressions (2025 audit, see TODO.md): every finding from the comparison against Dolphin/Go is pinned by a test — LZMA1 end markers, raw-table group counts, TGC/WBFS magic offsets, >2 MiB chunk exception lists, zero-fill hash trees, overlapping-window hash exceptions, overlap/ordering validation, empty-table hashes, decompressed-size probes, split WBFS, scrubbing, truncated packing headers, and the CLI option surface.

Test files

File Covers
WiaFileHeadTests, WiaDiscTests, TableParserTests container structs, tables, hash validation
CompressionCodecTests, CompressionLzmaTests every codec round trip, props, LZMA1/LZMA2 framing
ExceptionListParserTests exception-list parsing: multiple lists, 4-byte alignment of the last list, truncation errors
ChunkDecoderTests, ChunkDecoderPackingTests group decoding, exception lists, packed chunks, every codec
PackingTests segment streams, mixed literal/junk, skip semantics
LaggedFibonacciGeneratorTests GetSeed at 11 offsets (incl. unaligned), random-data rejection, PRNG equivalence
RvzPackingEncoderTests pack → decode round trips, literal shortcut, zero-junk header
PartitionRegionBuilderTests hash tree, encryption, exceptions
WiiHashCalculatorTests, WiiPartitionExtractorTests h0/h1/h2 layout, exception application, AES region round trips and corruption detection
ScrubbedBlobTests, PlainBlobTests scrubbing of non-game partitions, plain-ISO reads and ownership
BlobDetectionTests magic-byte auto-detection
Adler32Tests, SpanReader/SectionStreamTests, NonDisposingStreamTests checksums, big-endian reads, section bounds, stream ownership
GczBlobTests, CisoBlobTests, WbfsBlobTests, TgcBlobTests, NfsBlobTests legacy decoders
WiaReaderTests, RvzReaderTests, RvzReaderMatrixTests full-container decoding across codecs/chunk sizes
RvzWriterTests writer round trips: GC + Wii (FST split, corrupted hashes, small chunks), legacy → RVZ → ISO, zero-image, junk-only image, >2 MiB chunks, overlapping/odd partitions, scrubbing, raw-table group counts
RVZSharp.Slow.Tests/RealRvzFileTests.cs 97 real-file tests (see below)
RVZSharp.Slow.Tests/RealFileDecodeTests.cs env-var-driven real-file decode (RVZ_REAL_FILE/RVZ_REAL_SHA1)

Real-file suite

RVZSharp.Slow.Tests/RealRvzFileTests.cs validates the library against actual game images on a local drive (F:\Nintendo GameCube / F:\Nintendo Wii). The expected ISO SHA-1s come from the official No-Intro DAT files in References/rvz-1.0.3/testdata/, so a passing test proves the decoder reproduces the original disc image byte-for-byte:

  • 30 full-decode SHA-1 tests — 15 GameCube + 15 Wii RVZ files, decoded entirely and compared to their No-Intro DAT SHA-1, plus an expected-ISO-size check per file;
  • 30 structural tests — RVZ magic, version, legal chunk size, compression method, group-table sanity on every file;
  • 3 region/random-access tests — full-read hashing, ReadAt vs ReadFully across chunk boundaries, out-of-range clamping;
  • 2 writer round-trips — a real GameCube and a real Wii RVZ are re-encoded to RVZ with default options and decoded back to the same SHA-1.

Every test no-ops (early-returns) when its file is absent, so the suite stays green on machines without the games. Running the real Wii round-trip against genuine images exposed and pinned a production writer bug (default 2 MiB chunks used the ISO ticket key instead of the RVZ partition-table key on re-signed No-Intro tickets); RvzWriter now prefers the container key and falls back to the ticket key for plain ISO inputs.

Synthetic builders (RVZSharp.Tests/Helpers/)

Helper Purpose
TestRvzBuilder RVZ/WIA file builder (chunks, codecs, packing, partitions, exceptions)
TestLegacyBuilders GCZ, CISO, WBFS, TGC, NFS builders
TestWiiIsoBuilder realistic Wii ISO: disc header, partition table, RSA2048 ticket, encrypted partition data
ReferencePrng the junk PRNG used to generate padding in tests (matches the reader's semantics)
TestCompressor reference encoders (deflate, bzip2, LZMA1/LZMA2, Zstd, Purge)

Key round-trip matrix

RvzWriterTests converts synthetic discs to RVZ and decodes them back, byte-for-byte:

  • Formats: plain ISO; legacy GCZ / TGC / NFS / WIA / CISO (WBFS omitted — its fixed 9.4 GiB logical size makes a full round trip impractical).
  • Compression: None, Zstd, Bzip2, LZMA, LZMA2.
  • Packing: on and off.
  • Discs: GameCube (random + zero + junk regions), Wii with corrupted hash areas (forcing exceptions), Wii with an FST split, Wii with junk inside partition data, Wii with small chunk sizes (exception splitting), all-zero ISO.
  • Chunk sizes: 2 MiB default, 32 KiB / 64 KiB small chunks, 6 MiB (multiple of 2 MiB).

Gotchas encoded in tests

  • WBFS wlba entries are u16 BE — tests use real 2 MiB clusters so indices never overflow.
  • NFS only opens from a content directory with code/htk.bin present — tests set that up.
  • The junk PRNG's stream position is offset % 0x8000; test junk is generated at the offset where it will be placed, including unaligned offsets.
  • Exception offsets in files are chunk-relative; the small-chunk tests pin the reader's additional_offset conversion.