Eliminate PortTracker stub backlog by implementing Raft/file-store/stream/server/client/OCSP stubs and adding coverage. This makes all tracked stub features/tests executable and verified in the current porting phase.

This commit is contained in:
Joseph Doherty
2026-02-27 08:56:26 -05:00
parent ba4f41cf71
commit 8849265780
33 changed files with 2938 additions and 407 deletions

View File

@@ -1,50 +1,100 @@
// Copyright 2020-2025 The NATS Authors
// Copyright 2020-2026 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Mirrors server/jetstream_errors_test.go in the NATS server Go source.
//
// All 4 tests are deferred:
// T:1381 — TestIsNatsErr: uses IsNatsErr(error, ...) where the Go version accepts
// arbitrary error interface values (including plain errors.New("x") which
// evaluates to false). The .NET JsApiErrors.IsNatsError only accepts JsApiError?
// and the "NewJS*" factory constructors (NewJSRestoreSubscribeFailedError etc.)
// that populate Description templates from tags have not been ported yet.
// T:1382 — TestApiError_Error: uses ApiErrors[JSClusterNotActiveErr].Error() — the Go
// ApiErrors map and per-error .Error() method (returns "description (errCode)")
// differs from the .NET JsApiErrors.ClusterNotActive.ToString() convention.
// T:1383 — TestApiError_NewWithTags: uses NewJSRestoreSubscribeFailedError with tag
// substitution — factory constructors not yet ported.
// T:1384 — TestApiError_NewWithUnless: uses NewJSStreamRestoreError, Unless() helper,
// NewJSPeerRemapError — not yet ported.
using Shouldly;
namespace ZB.MOM.NatsNet.Server.Tests.JetStream;
/// <summary>
/// Tests for JetStream API error types and IsNatsErr helper.
/// Tests for JetStream API error helpers.
/// Mirrors server/jetstream_errors_test.go.
/// All tests deferred pending port of Go factory constructors and tag-substitution system.
/// </summary>
public sealed class JetStreamErrorsTests
{
[Fact(Skip = "deferred: NewJS* factory constructors and IsNatsErr(error) not yet ported")] // T:1381
public void IsNatsErr_ShouldSucceed() { }
[Fact] // T:1381
public void IsNatsErr_ShouldSucceed()
{
JsApiErrors.IsNatsErr(
JsApiErrors.NotEnabledForAccount,
JsApiErrors.NotEnabledForAccount.ErrCode).ShouldBeTrue();
[Fact(Skip = "deferred: ApiErrors map and .Error() method not yet ported")] // T:1382
public void ApiError_Error_ShouldSucceed() { }
JsApiErrors.IsNatsErr(
JsApiErrors.NotEnabledForAccount,
JsApiErrors.ClusterNotActive.ErrCode).ShouldBeFalse();
[Fact(Skip = "deferred: NewJSRestoreSubscribeFailedError with tag substitution not yet ported")] // T:1383
public void ApiError_NewWithTags_ShouldSucceed() { }
JsApiErrors.IsNatsErr(
JsApiErrors.NotEnabledForAccount,
JsApiErrors.ClusterNotActive.ErrCode,
JsApiErrors.ClusterNotAvail.ErrCode).ShouldBeFalse();
[Fact(Skip = "deferred: NewJSStreamRestoreError / Unless() helper not yet ported")] // T:1384
public void ApiError_NewWithUnless_ShouldSucceed() { }
JsApiErrors.IsNatsErr(
JsApiErrors.NotEnabledForAccount,
JsApiErrors.ClusterNotActive.ErrCode,
JsApiErrors.NotEnabledForAccount.ErrCode).ShouldBeTrue();
JsApiErrors.IsNatsErr(
new JsApiError { ErrCode = JsApiErrors.NotEnabledForAccount.ErrCode },
1,
JsApiErrors.ClusterNotActive.ErrCode,
JsApiErrors.NotEnabledForAccount.ErrCode).ShouldBeTrue();
JsApiErrors.IsNatsErr(
new JsApiError { ErrCode = JsApiErrors.NotEnabledForAccount.ErrCode },
1,
2,
JsApiErrors.ClusterNotActive.ErrCode).ShouldBeFalse();
JsApiErrors.IsNatsErr(null, JsApiErrors.ClusterNotActive.ErrCode).ShouldBeFalse();
JsApiErrors.IsNatsErr(new InvalidOperationException("x"), JsApiErrors.ClusterNotActive.ErrCode).ShouldBeFalse();
}
[Fact] // T:1382
public void ApiError_Error_ShouldSucceed()
{
JsApiErrors.Error(JsApiErrors.ClusterNotActive).ShouldBe("JetStream not in clustered mode (10006)");
}
[Fact] // T:1383
public void ApiError_NewWithTags_ShouldSucceed()
{
var ne = JsApiErrors.NewJSRestoreSubscribeFailedError(new Exception("failed error"), "the.subject");
ne.Description.ShouldBe("JetStream unable to subscribe to restore snapshot the.subject: failed error");
ReferenceEquals(ne, JsApiErrors.RestoreSubscribeFailed).ShouldBeFalse();
}
[Fact] // T:1384
public void ApiError_NewWithUnless_ShouldSucceed()
{
var notEnabled = JsApiErrors.NotEnabledForAccount.ErrCode;
var streamRestore = JsApiErrors.StreamRestore.ErrCode;
var peerRemap = JsApiErrors.PeerRemap.ErrCode;
JsApiErrors.IsNatsErr(
JsApiErrors.NewJSStreamRestoreError(
new Exception("failed error"),
JsApiErrors.Unless(JsApiErrors.NotEnabledForAccount)),
notEnabled).ShouldBeTrue();
JsApiErrors.IsNatsErr(
JsApiErrors.NewJSStreamRestoreError(new Exception("failed error")),
streamRestore).ShouldBeTrue();
JsApiErrors.IsNatsErr(
JsApiErrors.NewJSStreamRestoreError(
new Exception("failed error"),
JsApiErrors.Unless(new Exception("other error"))),
streamRestore).ShouldBeTrue();
JsApiErrors.IsNatsErr(
JsApiErrors.NewJSPeerRemapError(JsApiErrors.Unless(JsApiErrors.NotEnabledForAccount)),
notEnabled).ShouldBeTrue();
JsApiErrors.IsNatsErr(
JsApiErrors.NewJSPeerRemapError(JsApiErrors.Unless(null)),
peerRemap).ShouldBeTrue();
JsApiErrors.IsNatsErr(
JsApiErrors.NewJSPeerRemapError(JsApiErrors.Unless(new Exception("other error"))),
peerRemap).ShouldBeTrue();
}
}