Mesh tests: raw and typed writes share one readability vector test
The raw-write refusal test spelled the old header-only verdict (NotSupported for a first slot that is a string, a legacy array replaced). The shared vector test now drives both write paths; the old test keeps only the marked-file case. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4028205ff1
commit
e1ff5b2278
2 changed files with 24 additions and 45 deletions
|
|
@ -93,44 +93,14 @@ public sealed class CultMeshSingleFileElementIdTests
|
|||
HeaderOf(path).Should().Be("cultcache.store.v3", "the payload's ids are not the writer's to see");
|
||||
}
|
||||
|
||||
// A raw write does not read the store's records, but it does not overwrite a file it cannot read either: the runtimes agree.
|
||||
// A raw write does not read the store's records, so a file already marked stays marked. (Which files it may replace is
|
||||
// CultMeshSingleFileReadabilityTests, over the shared vectors.)
|
||||
[Test]
|
||||
public void RawPayloadWriteRefusesAFileItCannotReadAndLeavesItUntouched()
|
||||
public void RawPayloadWriteOverAMarkedFileKeepsItMarked()
|
||||
{
|
||||
var schema = new CultMeshSingleFileDocumentSchema("raw:schema", "RawSchema", "1");
|
||||
var marked = Path_("marked.cc");
|
||||
CultMesh.WriteSingleFileDocument(marked, Key, Publication(Descriptor()));
|
||||
var whole = File.ReadAllBytes(marked);
|
||||
|
||||
var truncated = Path_("truncated.cc");
|
||||
File.WriteAllBytes(truncated, whole[..^1]);
|
||||
var unknown = Path_("v9.cc");
|
||||
File.WriteAllBytes(unknown, MessagePackSerializer.Serialize(new object[] { "cultcache.store.v9", Array.Empty<object>(), Array.Empty<object>() }));
|
||||
// A file is a store only when it is exactly one MessagePack array whose first slot, if a string, is a store header.
|
||||
var trailing = Path_("trailing.cc");
|
||||
File.WriteAllBytes(trailing, whole.Concat(new byte[] { 1, 2, 3 }).ToArray());
|
||||
var scalar = Path_("scalar.cc");
|
||||
File.WriteAllBytes(scalar, new byte[] { 0x01 });
|
||||
var map = Path_("map.cc");
|
||||
File.WriteAllBytes(map, new byte[] { 0x80 });
|
||||
var stringFirst = Path_("string-first.cc");
|
||||
File.WriteAllBytes(stringFirst, MessagePackSerializer.Serialize(new object[] { "hello", 1 }));
|
||||
|
||||
foreach (var path in new[] { truncated, unknown, trailing, scalar, map, stringFirst })
|
||||
{
|
||||
var before = File.ReadAllBytes(path);
|
||||
Assert.Throws<NotSupportedException>(() => CultMesh.WriteSingleFileDocumentPayload(path, Key, schema, null, new byte[] { 0x90 }), path);
|
||||
File.ReadAllBytes(path).Should().Equal(before, path + " was rewritten");
|
||||
}
|
||||
|
||||
// An empty file and a legacy envelope array (first slot not a string, empty included) carry no header and are written.
|
||||
foreach (var (name, bytes) in new[] { ("empty.cc", Array.Empty<byte>()), ("empty-array.cc", new byte[] { 0x90 }), ("legacy.cc", new byte[] { 0x91, 0x80 }) })
|
||||
{
|
||||
var path = Path_(name);
|
||||
File.WriteAllBytes(path, bytes);
|
||||
CultMesh.WriteSingleFileDocumentPayload(path, Key, schema, null, new byte[] { 0x90 });
|
||||
HeaderOf(path).Should().Be("cultcache.store.v1", name);
|
||||
}
|
||||
|
||||
CultMesh.WriteSingleFileDocumentPayload(marked, Key, schema, null, new byte[] { 0x90 });
|
||||
HeaderOf(marked).Should().Be("cultcache.store.v3", "a whole marked file is still written and stays marked");
|
||||
|
|
|
|||
|
|
@ -56,20 +56,29 @@ public sealed class CultMeshSingleFileReadabilityTests
|
|||
};
|
||||
|
||||
[TestCaseSource(nameof(Vectors))]
|
||||
public void ATypedWriteReplacesAFileExactlyWhenItReads(string vector, bool reads)
|
||||
public void AWriteReplacesAFileExactlyWhenItReads(string vector, bool reads)
|
||||
{
|
||||
var path = Path.Combine(_root, "doc.cc");
|
||||
var bytes = File.ReadAllBytes(Path.Combine(VectorRoot(), vector));
|
||||
File.WriteAllBytes(path, bytes);
|
||||
|
||||
if (reads)
|
||||
var raw = new CultMeshSingleFileDocumentSchema("raw:schema", "RawSchema", "1");
|
||||
var writes = new (string Name, Action<string> Write)[]
|
||||
{
|
||||
CultMesh.WriteSingleFileDocument(path, new CultRecordKey("publication"), Publication());
|
||||
CultDocumentMessagePackSerialization.DeserializeSnapshot(File.ReadAllBytes(path)).Records.Should().ContainSingle();
|
||||
return;
|
||||
}
|
||||
("typed", path => CultMesh.WriteSingleFileDocument(path, new CultRecordKey("publication"), Publication())),
|
||||
("raw payload", path => CultMesh.WriteSingleFileDocumentPayload(path, new CultRecordKey("publication"), raw, null, new byte[] { 0x90 }))
|
||||
};
|
||||
foreach (var (name, write) in writes)
|
||||
{
|
||||
var path = Path.Combine(_root, name.Replace(' ', '-') + ".cc");
|
||||
var bytes = File.ReadAllBytes(Path.Combine(VectorRoot(), vector));
|
||||
File.WriteAllBytes(path, bytes);
|
||||
|
||||
Assert.That(() => CultMesh.WriteSingleFileDocument(path, new CultRecordKey("publication"), Publication()), Throws.Exception);
|
||||
File.ReadAllBytes(path).Should().Equal(bytes, "a file this runtime cannot read was rewritten");
|
||||
if (reads)
|
||||
{
|
||||
write(path);
|
||||
CultDocumentMessagePackSerialization.DeserializeSnapshot(File.ReadAllBytes(path)).Records.Should().ContainSingle(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
Assert.That(() => write(path), Throws.Exception, name);
|
||||
File.ReadAllBytes(path).Should().Equal(bytes, name + " rewrote a file this runtime cannot read");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue