Caching tests: an empty store file is refused; a missing file or [0x90] is empty

Pins the C# side of the cross-runtime rule the Rust, Python and TS runtimes
now share. C# already refused a zero-byte file (the snapshot reader runs out
of bytes at the array header); this test keeps it that way. Its exception is
still EndOfStreamException, an IOException: that overlap belongs to R3's C#
work.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-30 17:05:15 +02:00
commit 2d7a3c78eb

View file

@ -167,6 +167,41 @@ namespace GameCult.Caching.Tests
Throws.TypeOf<NotSupportedException>().With.Message.Contains("format version"));
}
// Every runtime reads a store file the same way: a missing file is an empty store, an existing empty file is not
// a store (no CultCache writer leaves one), and an empty array carries no header, so it claims no format and is an
// empty store too.
[Test]
public async Task SingleFileRefusesAnEmptyFileAndOpensAMissingFileOrAnEmptyArrayAsEmpty()
{
var root = Path.Combine(Path.GetTempPath(), $"cultlib-empty-{Guid.NewGuid():N}");
Directory.CreateDirectory(root);
try
{
var empty = Path.Combine(root, "empty.msgpack");
File.WriteAllBytes(empty, Array.Empty<byte>());
using (var cache = new CultCache())
{
Assert.Catch(() => cache.AddBackingStore(new SingleFileMessagePackBackingStore(empty)));
Assert.That(cache.BackingStores, Is.Empty);
}
Assert.That(File.ReadAllBytes(empty), Is.Empty);
var emptyArray = Path.Combine(root, "empty-array.msgpack");
File.WriteAllBytes(emptyArray, new byte[] { 0x90 });
foreach (var path in new[] { Path.Combine(root, "missing.msgpack"), emptyArray })
{
using var cache = new CultCache();
cache.AddBackingStore(new SingleFileMessagePackBackingStore(path));
await cache.PullAllBackingStoresAsync();
Assert.That(cache.GetAll<PreCut2FixtureItem>(), Is.Empty, path);
}
}
finally
{
if (Directory.Exists(root)) Directory.Delete(root, recursive: true);
}
}
[Test]
public void V1StoreWrittenAtTheBaseCommitStillDecodesByteForByte()
{