feat(batch10): task3 implement ocsp cache core stats and compression
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
|
||||
using Shouldly;
|
||||
using ZB.MOM.NatsNet.Server.Auth.CertificateIdentityProvider;
|
||||
using ZB.MOM.NatsNet.Server.Auth.Ocsp;
|
||||
|
||||
namespace ZB.MOM.NatsNet.Server.Tests.Auth;
|
||||
@@ -9,25 +10,86 @@ namespace ZB.MOM.NatsNet.Server.Tests.Auth;
|
||||
public sealed class OcspResponseCacheTests
|
||||
{
|
||||
[Fact]
|
||||
public void LocalDirCache_GetPutRemove_ShouldPersistToDisk()
|
||||
public void LocalDirCache_PutReplaceDelete_AdjustsStats()
|
||||
{
|
||||
var dir = Path.Combine(Path.GetTempPath(), $"ocsp-{Guid.NewGuid():N}");
|
||||
Directory.CreateDirectory(dir);
|
||||
try
|
||||
{
|
||||
var cache = new LocalDirCache(dir);
|
||||
cache.Get("abc").ShouldBeNull();
|
||||
var cache = new LocalDirCache(Path.Combine(Path.GetTempPath(), $"ocsp-{Guid.NewGuid():N}"));
|
||||
cache.Start();
|
||||
|
||||
cache.Put("abc", [1, 2, 3]);
|
||||
cache.Get("abc").ShouldBe([1, 2, 3]);
|
||||
cache.Put("k1", CreateResponse(OcspStatusAssertion.Good, [1, 2, 3]), "subj");
|
||||
cache.Put("k1", CreateResponse(OcspStatusAssertion.Revoked, [4, 5, 6]), "subj");
|
||||
cache.Put("k2", CreateResponse(OcspStatusAssertion.Unknown, [7, 8]), "subj");
|
||||
|
||||
cache.Remove("abc");
|
||||
cache.Get("abc").ShouldBeNull();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(dir, recursive: true);
|
||||
}
|
||||
var statsAfterPut = cache.Stats();
|
||||
statsAfterPut.ShouldNotBeNull();
|
||||
statsAfterPut.Responses.ShouldBe(2);
|
||||
statsAfterPut.Goods.ShouldBe(0);
|
||||
statsAfterPut.Revokes.ShouldBe(1);
|
||||
statsAfterPut.Unknowns.ShouldBe(1);
|
||||
|
||||
cache.Delete("k1", wasMiss: false);
|
||||
|
||||
var statsAfterDelete = cache.Stats();
|
||||
statsAfterDelete.ShouldNotBeNull();
|
||||
statsAfterDelete.Responses.ShouldBe(1);
|
||||
statsAfterDelete.Revokes.ShouldBe(0);
|
||||
statsAfterDelete.Unknowns.ShouldBe(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LocalDirCache_DeletePreserveRevoked_WithMiss_AdjustsHitToMiss()
|
||||
{
|
||||
var config = OcspHandler.NewOCSPResponseCacheConfig();
|
||||
config.PreserveRevoked = true;
|
||||
|
||||
var cache = new LocalDirCache(config);
|
||||
cache.Start();
|
||||
cache.Put("k1", CreateResponse(OcspStatusAssertion.Revoked, [9, 9, 9]), "subj");
|
||||
cache.Get("k1").ShouldNotBeNull();
|
||||
|
||||
cache.Delete("k1", wasMiss: true);
|
||||
|
||||
var stats = cache.Stats();
|
||||
stats.ShouldNotBeNull();
|
||||
stats.Responses.ShouldBe(1);
|
||||
stats.Revokes.ShouldBe(1);
|
||||
stats.Hits.ShouldBe(0);
|
||||
stats.Misses.ShouldBe(1);
|
||||
cache.Get("k1").ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LocalDirCache_OnlineTypeConfigStats_FollowLifecycle()
|
||||
{
|
||||
var config = OcspHandler.NewOCSPResponseCacheConfig();
|
||||
var cache = new LocalDirCache(config);
|
||||
|
||||
cache.Online().ShouldBeFalse();
|
||||
cache.Type().ShouldBe("local");
|
||||
cache.Config().LocalStore.ShouldBe(config.LocalStore);
|
||||
cache.Stats().ShouldBeNull();
|
||||
|
||||
cache.Start();
|
||||
cache.Online().ShouldBeTrue();
|
||||
cache.Stats().ShouldNotBeNull();
|
||||
|
||||
cache.Stop();
|
||||
cache.Online().ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LocalDirCache_CompressDecompress_RoundTripsPayload()
|
||||
{
|
||||
var cache = new LocalDirCache(Path.Combine(Path.GetTempPath(), $"ocsp-{Guid.NewGuid():N}"));
|
||||
var payload = "ocsp-cache-roundtrip-data"u8.ToArray();
|
||||
|
||||
var (compressed, compressError) = cache.Compress(payload);
|
||||
compressError.ShouldBeNull();
|
||||
compressed.ShouldNotBeNull();
|
||||
|
||||
var (decompressed, decompressError) = cache.Decompress(compressed!);
|
||||
decompressError.ShouldBeNull();
|
||||
decompressed.ShouldNotBeNull();
|
||||
decompressed.ShouldBe(payload);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -45,37 +107,19 @@ public sealed class OcspResponseCacheTests
|
||||
|
||||
noOp.Put("k", [5]);
|
||||
noOp.Get("k").ShouldBeNull();
|
||||
noOp.Remove("k"); // alias to Delete
|
||||
noOp.Remove("k");
|
||||
noOp.Delete("k");
|
||||
|
||||
noOp.Stop();
|
||||
noOp.Online().ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OcspMonitor_StartAndStop_ShouldLoadStaple()
|
||||
{
|
||||
var dir = Path.Combine(Path.GetTempPath(), $"ocsp-monitor-{Guid.NewGuid():N}");
|
||||
Directory.CreateDirectory(dir);
|
||||
try
|
||||
private static OcspResponse CreateResponse(OcspStatusAssertion status, byte[] raw) =>
|
||||
new()
|
||||
{
|
||||
var stapleFile = Path.Combine(dir, "staple.bin");
|
||||
File.WriteAllBytes(stapleFile, [9, 9]);
|
||||
|
||||
var monitor = new OcspMonitor
|
||||
{
|
||||
OcspStapleFile = stapleFile,
|
||||
CheckInterval = TimeSpan.FromMilliseconds(10),
|
||||
};
|
||||
|
||||
monitor.Start();
|
||||
Thread.Sleep(30);
|
||||
monitor.GetStaple().ShouldBe([9, 9]);
|
||||
monitor.Stop();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(dir, recursive: true);
|
||||
}
|
||||
}
|
||||
Status = status,
|
||||
ThisUpdate = DateTime.UtcNow.AddMinutes(-1),
|
||||
NextUpdate = DateTime.UtcNow.AddMinutes(10),
|
||||
Raw = raw,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user