C# store header tests: a marked header stays marked over a copied record; the directory skew test holds the record ahead in the cache

The foreign-record header test expected a marked header to drop while a record was copied
forward, which the header rule no longer does. A directory store loads a record from its
page, not the manifest, so its skew test makes both writers hold the record ahead instead of
editing the manifest.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-03 07:09:28 +02:00
commit ea8ca2e98b
2 changed files with 18 additions and 14 deletions

View file

@ -551,27 +551,19 @@ namespace GameCult.Caching.Tests
}
// A writer cannot see whether a foreign record holds element ids, so a store marked as holding them stays marked while it
// carries one. Without one, a whole-view write decides by what it writes, and nothing here holds an id.
// carries one: a write that copies any record forward keeps the mark.
[Test]
public void AMarkedHeaderStaysMarkedWhileTheStoreCarriesAForeignRecord(
[Values(Write.Flush, Write.Commit)] Write write,
[Values] bool carriesForeign)
public void AMarkedHeaderStaysMarkedWhileTheStoreCarriesAForeignRecord([Values(Write.Flush, Write.Commit)] Write write)
{
var path = Seeded("marked.cc", directory: false);
var snapshot = Read(path);
snapshot.FormatVersion = CultPersistedStoreSnapshot.FormatV3;
if (!carriesForeign)
{
snapshot.Records = snapshot.Records.Where(record => record.Key != W.Value).ToArray();
snapshot.SchemaCatalog = snapshot.SchemaCatalog.Where(entry => entry.SchemaId != WidgetId).ToArray();
}
File.WriteAllBytes(path, CultDocumentMessagePackSerialization.SerializeSnapshot(snapshot));
using (var cache = Open(path, DeckOnly, directory: false))
Land(cache, write, E, DeckOf("e"));
Assert.That(Read(path).FormatVersion, Is.EqualTo(carriesForeign ? CultPersistedStoreSnapshot.FormatV3 : CultPersistedStoreSnapshot.FormatV1));
Assert.That(Read(path).FormatVersion, Is.EqualTo(CultPersistedStoreSnapshot.FormatV3));
}
private const string OtherRuntimeId = "other.runtime.deck";

View file

@ -565,11 +565,23 @@ namespace GameCult.Caching.Tests
Seed(path, directory, "k");
var k = new CultRecordKey("k");
var ahead = DateTimeOffset.UtcNow.AddHours(1).ToString("O", CultureInfo.InvariantCulture);
var snapshot = Read(path);
snapshot.Records.Single(record => record.Key == "k").StoredAt = ahead;
Write(path, snapshot);
// A single file holds the record at that storedAt. A directory store loads a record from its page, which the manifest
// does not own, so there both writers are made to hold it ahead: a stage then mints from it, as a skewed clock does.
if (!directory)
{
var snapshot = Read(path);
snapshot.Records.Single(record => record.Key == "k").StoredAt = ahead;
Write(path, snapshot);
}
using var a = Open(path, directory);
using var b = Open(path, directory);
if (directory)
{
a.GetStored(k)!.StoredAt = ahead;
b.GetStored(k)!.StoredAt = ahead;
}
if (commit)
b.Commit(batch => batch.Upsert(typeof(WsItem), new WsItem { Name = "name-k", Note = "by-b" }, k));
else