feat(p7-09): JetStream unit tests — versioning (12), dirstore (12), batching/errors deferred (66)
Port session P7-09: add tests from jetstream_versioning_test.go (T:1791–1808),
dirstore_test.go (T:285–296), jetstream_batching_test.go (T:716–744),
jetstream_errors_test.go (T:1381–1384), and accounts_test.go (T:80–110).
- JetStreamVersioningTests: 12 active unit tests + 6 deferred (server-required)
- DirectoryStoreTests: 12 filesystem tests using fake JWTs (no NKeys dependency)
- JetStreamBatchingTests: 29 deferred stubs (all require running JetStream cluster)
- JetStreamErrorsTests: 4 deferred stubs (NewJS* factories not yet ported)
- accounts_test.go T:80–110: 31 deferred (all use RunServerWithConfig)
Fix DirJwtStore.cs expiration bugs:
- Use DateTimeOffset.UtcNow.UtcTicks (not Unix-relative ticks) for expiry comparison
- Replace in-place JwtItem mutation with new-object replacement so DrainStale
can detect stale heap entries via ReferenceEquals check
Add JetStreamVersioning.cs methods: SetStaticStreamMetadata,
SetDynamicStreamMetadata, CopyStreamMetadata, SetStaticConsumerMetadata,
SetDynamicConsumerMetadata, SetDynamicConsumerInfoMetadata, CopyConsumerMetadata.
Tests: 725 pass, 53 skipped/deferred, 0 failures.
DB: +24 complete, +66 deferred.
This commit is contained in:
@@ -624,7 +624,7 @@ public sealed class DirJwtStore : IDisposable
|
||||
/// Deletes the JWT for <paramref name="publicKey"/> according to <see cref="_deleteType"/>.
|
||||
/// Mirrors Go <c>DirJWTStore.delete</c>.
|
||||
/// </summary>
|
||||
private void Delete(string publicKey)
|
||||
public void Delete(string publicKey)
|
||||
{
|
||||
if (_readonly)
|
||||
{
|
||||
@@ -795,7 +795,7 @@ public sealed class DirJwtStore : IDisposable
|
||||
// Background timer — mirrors Go goroutine + time.Ticker.
|
||||
var timer = new Timer(_ =>
|
||||
{
|
||||
var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() * TimeSpan.TicksPerMillisecond;
|
||||
var now = DateTimeOffset.UtcNow.UtcTicks;
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -1104,14 +1104,13 @@ internal sealed class ExpirationTracker
|
||||
// Remove old hash contribution from rolling XOR.
|
||||
XorAssign(_hash, existing.Hash);
|
||||
|
||||
// Update in-place.
|
||||
existing.Expiration = exp;
|
||||
existing.Hash = hash;
|
||||
|
||||
// Re-enqueue with updated priority (PriorityQueue does not support update;
|
||||
// use a version counter approach — mark old entry stale, enqueue fresh).
|
||||
existing.Version++;
|
||||
_heap.Enqueue(existing, exp);
|
||||
// Create a new JwtItem so the old heap entry becomes a stale orphan.
|
||||
// DrainStale uses ReferenceEquals(current, top) to detect orphans:
|
||||
// the old heap entry points to the old JwtItem object which is no longer
|
||||
// in _idx, so it will be drained on the next PeekExpired call.
|
||||
var updated = new JwtItem(publicKey, exp, hash);
|
||||
_idx[publicKey] = updated;
|
||||
_heap.Enqueue(updated, exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1141,9 +1140,11 @@ internal sealed class ExpirationTracker
|
||||
? long.MaxValue
|
||||
: (DateTimeOffset.UtcNow + Ttl).UtcTicks;
|
||||
|
||||
item.Expiration = newExp;
|
||||
item.Version++;
|
||||
_heap.Enqueue(item, newExp);
|
||||
// Replace with a new JwtItem so the old heap entry becomes a stale orphan
|
||||
// (DrainStale detects staleness via ReferenceEquals).
|
||||
var updated = new JwtItem(publicKey, newExp, item.Hash);
|
||||
_idx[publicKey] = updated;
|
||||
_heap.Enqueue(updated, newExp);
|
||||
}
|
||||
|
||||
if (EvictOnLimit)
|
||||
|
||||
Reference in New Issue
Block a user