Skip to content

Add SnapshotFormat: audio file vs MD5 checksum#12

Merged
jcavar merged 1 commit intomainfrom
add-snapshot-format-checksum
Feb 27, 2026
Merged

Add SnapshotFormat: audio file vs MD5 checksum#12
jcavar merged 1 commit intomainfrom
add-snapshot-format-checksum

Conversation

@jcavar
Copy link
Collaborator

@jcavar jcavar commented Feb 25, 2026

Summary

  • Adds a SnapshotFormat enum (.audio / .checksum) so users can choose between full ALAC .caf snapshots (current behavior) or lightweight .md5 checksum files (~32 bytes each)
  • Default is .audio, preserving full backward compatibility — no changes needed for existing tests
  • In checksum mode, the ALAC file is still written to a temp location to compute its MD5 hash; the hash becomes the stored snapshot artifact

Test plan

  • All existing tests pass unchanged (backward compat)
  • New checksumRoundTrip test: record + verify round-trip with .checksum format
  • New checksumMultiBuffer test: multi-buffer checksum with indexed naming (.1.md5, .2.md5)
  • .md5 files contain 32-character hex checksums

@jcavar jcavar force-pushed the add-snapshot-format-checksum branch from 70f8b43 to 262b79a Compare February 25, 2026 09:58
For repositories with many audio snapshot tests, .caf files can bloat
the repo. This adds a SnapshotFormat enum (.audio / .checksum) so users
can opt into lightweight 32-byte .md5 checksum files instead of full
ALAC audio snapshots. Default is .audio, preserving full backward
compatibility.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in snapshot artifact format that stores lightweight MD5 checksum files instead of full ALAC .caf audio snapshots, while keeping .audio as the default for backward compatibility.

Changes:

  • Introduce SnapshotFormat (.audio / .checksum) and thread it through AudioSnapshotTrait.
  • Implement checksum-mode recording/verifying by hashing a temporary .caf and storing/reading .md5 artifacts.
  • Add checksum-focused tests and commit expected .md5 snapshot fixtures (including multi-buffer indexed naming).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
Tests/AudioSnapshotTestingTests/AudioSnapshots/AudioSnapshotTestingTests/checksumRoundTrip.440hz.md5 Adds expected checksum snapshot fixture for round-trip test.
Tests/AudioSnapshotTestingTests/AudioSnapshots/AudioSnapshotTestingTests/checksumMultiBuffer.1.md5 Adds expected checksum snapshot fixture for multi-buffer test (buffer 1).
Tests/AudioSnapshotTestingTests/AudioSnapshots/AudioSnapshotTestingTests/checksumMultiBuffer.2.md5 Adds expected checksum snapshot fixture for multi-buffer test (buffer 2).
Tests/AudioSnapshotTestingTests/AudioSnapshotTestingTests.swift Adds new tests that run snapshotting in .checksum format.
Sources/AudioSnapshotTesting/Internal/AudioChecksumWriter.swift New helper for computing/writing/reading MD5 checksum artifacts.
Sources/AudioSnapshotTesting/Core/SnapshotFormat.swift New public enum that defines supported snapshot artifact formats.
Sources/AudioSnapshotTesting/Core/AudioSnapshotTrait.swift Adds format option to the trait and trait factory API.
Sources/AudioSnapshotTesting/Core/AudioSnapshotTesting.swift Implements .checksum behavior for snapshot pathing, recording, and verification.
Comments suppressed due to low confidence (3)

Sources/AudioSnapshotTesting/Internal/AudioChecksumWriter.swift:12

  • computeChecksum(of:) loads the entire audio file into memory via Data(contentsOf:). Snapshot audio can be non-trivial in size, so this can cause unnecessary memory spikes (and slower hashing). Consider streaming the file with FileHandle and updating an Insecure.MD5 digest incrementally (or at least using mapped reads) to keep memory usage bounded.
        let data = try Data(contentsOf: url)
        let digest = Insecure.MD5.hash(data: data)
        return digest.map { String(format: "%02x", $0) }.joined()

Sources/AudioSnapshotTesting/Core/AudioSnapshotTesting.swift:155

  • In .checksum mode, this writes a temporary .caf file to compute the hash but never removes it. Over time (especially across many tests/runs), the temp directory will accumulate snapshot audio artifacts. Consider deleting tempPath after the checksum is computed/written (e.g., defer { try? FileManager.default.removeItem(at: tempPath) }).
        case .checksum:
            let tempPath = context.temporaryAudioPath(index: index, count: bufferCount)
            try AudioFileWriter.write(buffer: buffers[index], to: tempPath, bitDepth: context.trait.bitDepth)
            let checksum = try AudioChecksumWriter.computeChecksum(of: tempPath)
            try AudioChecksumWriter.writeChecksum(checksum, to: path)

Sources/AudioSnapshotTesting/Core/AudioSnapshotTesting.swift:205

  • In .checksum mode, verification writes a temporary .caf for each buffer and leaves it behind after hashing. Consider cleaning up tempPath after computing the checksum to avoid leaving large temp files on disk (and to reduce the chance of interference between runs).
            let tempPath = context.temporaryAudioPath(index: index, count: buffers.count)
            try AudioFileWriter.write(buffer: buffer, to: tempPath, bitDepth: context.trait.bitDepth)
            let actualChecksum = try AudioChecksumWriter.computeChecksum(of: tempPath)
            let expectedChecksum = try AudioChecksumWriter.readChecksum(from: path)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Member

@aure aure left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks solid to me!

@jcavar jcavar merged commit 09eec88 into main Feb 27, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants