feat(batch14): complete group1 write path and wave1 tests
This commit is contained in:
@@ -203,6 +203,177 @@ public sealed partial class JetStreamFileStoreTests
|
||||
[Fact] // T:592
|
||||
public void FileStoreTrailingSkipMsgsFromStreamStateFile_ShouldSucceed() => RunWaveBScenario(nameof(FileStoreTrailingSkipMsgsFromStreamStateFile_ShouldSucceed));
|
||||
|
||||
[Fact] // T:549
|
||||
public void FileStoreTruncateRemovedBlock_ShouldSucceed()
|
||||
{
|
||||
WithStore((fs, _) =>
|
||||
{
|
||||
fs.StoreMsg("foo", null, "1"u8.ToArray(), 0).Seq.ShouldBe(1UL);
|
||||
fs.StoreMsg("foo", null, "2"u8.ToArray(), 0).Seq.ShouldBe(2UL);
|
||||
fs.StoreMsg("foo", null, "3"u8.ToArray(), 0).Seq.ShouldBe(3UL);
|
||||
|
||||
var before = fs.State();
|
||||
before.Msgs.ShouldBe(3UL);
|
||||
before.FirstSeq.ShouldBe(1UL);
|
||||
before.LastSeq.ShouldBe(3UL);
|
||||
before.NumDeleted.ShouldBe(0);
|
||||
|
||||
fs.RemoveMsg(2).Removed.ShouldBeTrue();
|
||||
var mid = fs.State();
|
||||
mid.Msgs.ShouldBe(2UL);
|
||||
mid.FirstSeq.ShouldBe(1UL);
|
||||
mid.LastSeq.ShouldBe(3UL);
|
||||
mid.NumDeleted.ShouldBe(1);
|
||||
|
||||
fs.Truncate(2);
|
||||
var after = fs.State();
|
||||
after.Msgs.ShouldBe(1UL);
|
||||
after.FirstSeq.ShouldBe(1UL);
|
||||
after.LastSeq.ShouldBe(2UL);
|
||||
after.NumDeleted.ShouldBe(1);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact] // T:551
|
||||
public void FileStoreRemoveBlockWithStaleStreamState_ShouldSucceed()
|
||||
{
|
||||
var root = NewRoot();
|
||||
Directory.CreateDirectory(root);
|
||||
|
||||
JetStreamFileStore? fs = null;
|
||||
JetStreamFileStore? reopened = null;
|
||||
try
|
||||
{
|
||||
fs = JetStreamFileStore.NewFileStore(new FileStoreConfig { StoreDir = root }, DefaultStreamConfig());
|
||||
var blk1 = CreateBlock(root, 1, "blk1-data"u8.ToArray());
|
||||
var blk2 = CreateBlock(root, 2, "blk2-data"u8.ToArray());
|
||||
var blk3 = CreateBlock(root, 3, "blk3-data"u8.ToArray());
|
||||
|
||||
fs.RecoverMsgBlock(1).Index.ShouldBe(1u);
|
||||
fs.RecoverMsgBlock(2).Index.ShouldBe(2u);
|
||||
fs.RecoverMsgBlock(3).Index.ShouldBe(3u);
|
||||
fs.Stop();
|
||||
fs = null;
|
||||
|
||||
File.Delete(blk2);
|
||||
|
||||
reopened = JetStreamFileStore.NewFileStore(new FileStoreConfig { StoreDir = root }, DefaultStreamConfig());
|
||||
reopened.RecoverMsgBlock(1).Index.ShouldBe(1u);
|
||||
reopened.RecoverMsgBlock(3).Index.ShouldBe(3u);
|
||||
Should.Throw<FileNotFoundException>(() => reopened.RecoverMsgBlock(2));
|
||||
}
|
||||
finally
|
||||
{
|
||||
reopened?.Stop();
|
||||
fs?.Stop();
|
||||
if (Directory.Exists(root))
|
||||
Directory.Delete(root, recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact] // T:561
|
||||
public void FileStoreTombstonesSelectNextFirstCleanup_ShouldSucceed()
|
||||
{
|
||||
WithStore((fs, _) =>
|
||||
{
|
||||
for (var i = 0; i < 100; i++)
|
||||
fs.StoreMsg("foo", null, "x"u8.ToArray(), 0);
|
||||
|
||||
for (ulong seq = 2; seq <= 100; seq++)
|
||||
fs.RemoveMsg(seq).Removed.ShouldBeTrue();
|
||||
|
||||
var before = fs.State();
|
||||
before.Msgs.ShouldBe(1UL);
|
||||
before.FirstSeq.ShouldBe(1UL);
|
||||
before.LastSeq.ShouldBe(100UL);
|
||||
|
||||
fs.RemoveMsg(1).Removed.ShouldBeTrue();
|
||||
var after = fs.State();
|
||||
after.Msgs.ShouldBe(0UL);
|
||||
after.FirstSeq.ShouldBe(101UL);
|
||||
after.LastSeq.ShouldBe(100UL);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact] // T:572
|
||||
public void FileStoreEmptyBlockContainsPriorTombstones_ShouldSucceed()
|
||||
{
|
||||
WithStore((fs, _) =>
|
||||
{
|
||||
fs.StoreMsg("foo", null, "1"u8.ToArray(), 0).Seq.ShouldBe(1UL);
|
||||
fs.StoreMsg("foo", null, "2"u8.ToArray(), 0).Seq.ShouldBe(2UL);
|
||||
fs.StoreMsg("foo", null, "3"u8.ToArray(), 0).Seq.ShouldBe(3UL);
|
||||
|
||||
fs.RemoveMsg(2).Removed.ShouldBeTrue();
|
||||
fs.RemoveMsg(3).Removed.ShouldBeTrue();
|
||||
|
||||
var mid = fs.State();
|
||||
mid.Msgs.ShouldBe(1UL);
|
||||
mid.FirstSeq.ShouldBe(1UL);
|
||||
mid.LastSeq.ShouldBe(3UL);
|
||||
mid.Deleted.ShouldContain(2UL);
|
||||
mid.Deleted.ShouldContain(3UL);
|
||||
|
||||
fs.StoreMsg("foo", null, "4"u8.ToArray(), 0).Seq.ShouldBe(4UL);
|
||||
fs.RemoveMsg(1).Removed.ShouldBeTrue();
|
||||
|
||||
var after = fs.State();
|
||||
after.Msgs.ShouldBe(1UL);
|
||||
after.FirstSeq.ShouldBe(4UL);
|
||||
after.LastSeq.ShouldBe(4UL);
|
||||
(after.Deleted ?? Array.Empty<ulong>()).ShouldBeEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
[Fact] // T:586
|
||||
public void FileStoreLoadNextMsgSkipAhead_ShouldSucceed()
|
||||
{
|
||||
WithStore((fs, _) =>
|
||||
{
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
var subj = i % 2 == 0 ? "a" : "c";
|
||||
fs.StoreMsg(subj, null, "x"u8.ToArray(), 0);
|
||||
}
|
||||
|
||||
fs.StoreMsg("b", null, "target"u8.ToArray(), 0).Seq.ShouldBe(11UL);
|
||||
|
||||
var (headSm, headSeq) = fs.LoadNextMsg("b", false, 0, null);
|
||||
headSm.ShouldNotBeNull();
|
||||
headSm!.Subject.ShouldBe("b");
|
||||
headSeq.ShouldBe(11UL);
|
||||
|
||||
var (interiorSm, interiorSeq) = fs.LoadNextMsg("b", false, 3, null);
|
||||
interiorSm.ShouldNotBeNull();
|
||||
interiorSm!.Subject.ShouldBe("b");
|
||||
interiorSeq.ShouldBe(11UL);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact] // T:587
|
||||
public void FileStoreLoadNextMsgMultiSkipAhead_ShouldSucceed()
|
||||
{
|
||||
WithStore((fs, _) =>
|
||||
{
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
var subj = i % 2 == 0 ? "a" : "c";
|
||||
fs.StoreMsg(subj, null, "x"u8.ToArray(), 0);
|
||||
}
|
||||
|
||||
fs.StoreMsg("b", null, "target"u8.ToArray(), 0).Seq.ShouldBe(11UL);
|
||||
|
||||
var (headSm, headSeq) = fs.LoadNextMsgMulti(new[] { "b", "d" }, 11, null);
|
||||
headSm.ShouldNotBeNull();
|
||||
headSm!.Subject.ShouldBe("b");
|
||||
headSeq.ShouldBe(11UL);
|
||||
|
||||
var (interiorSm, interiorSeq) = fs.LoadNextMsgMulti(new[] { "b", "d" }, 3, null);
|
||||
interiorSm.ShouldNotBeNull();
|
||||
interiorSeq.ShouldBeGreaterThanOrEqualTo(3UL);
|
||||
});
|
||||
}
|
||||
|
||||
private static void RunWaveBScenario(string scenario)
|
||||
{
|
||||
switch (scenario)
|
||||
|
||||
Reference in New Issue
Block a user