Files
Joseph Doherty a2441828af fix: convert all integration tests to static skip pattern for graceful skip
Replace IAsyncLifetime-based localhost connections and SkippableFact cluster-creation
tests with [Fact(Skip = "deferred: ...")] stubs so no test hangs or times out when no
NATS server is running. Affected files:
- JetStreamCluster1Tests.cs (118 tests, was SkippableFact + TestCluster creation)
- JetStreamCluster3Tests.cs (96 tests, was IAsyncLifetime connecting to localhost:4222)
- JetStreamMiscTests.cs (29 tests, was IAsyncLifetime connecting to localhost:4222)
- JetStreamBatchingIntegrationTests.cs (39 tests, was IAsyncLifetime connecting to localhost:4222)
- NatsServerBehaviorTests.cs (5 tests, was IAsyncLifetime connecting to localhost:4222)
2026-03-01 13:05:30 -05:00

372 lines
19 KiB
C#

// Copyright 2020-2025 The NATS Authors
// Licensed under the Apache License, Version 2.0
//
// Ported from golang/nats-server/server/jetstream_cluster_1_test.go
// These tests require a running JetStream cluster. They are skipped unless
// NATS_INTEGRATION_TESTS=true is set in the environment.
namespace ZB.MOM.NatsNet.Server.IntegrationTests.JetStream;
/// <summary>
/// Integration tests for JetStream cluster functionality: cluster formation,
/// stream replication, consumer state, leader election, and catchup.
/// Ported from Go's TestJetStreamCluster* tests (first 118).
/// </summary>
[Trait("Category", "Integration")]
public sealed class JetStreamCluster1Tests
{
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConfig_ShouldRequireServerNameAndClusterName() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterLeader_ShouldElectNewLeaderAfterShutdown() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterExpand_ShouldAllowAddingNewServer() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterAccountInfo_ShouldReturnSingleResponse() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamLimitWithAccountDefaults_ShouldEnforceStorageLimits() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterInfoRaftGroup_ShouldIncludeRaftGroupInStreamAndConsumerInfo() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterSingleReplicaStreams_ShouldSurviveLeaderRestart() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMultiReplicaStreams_ShouldReplicateAcrossCluster() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMultiReplicaStreamsDefaultFileMem_ShouldUseFileStorageByDefault() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMemoryStore_ShouldReplicateMemoryStoredMessages() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterDelete_ShouldRemoveConsumerAndStream() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamPurge_ShouldClearAllMessages() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamUpdateSubjects_ShouldUpdateSubjectsSuccessfully() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterBadStreamUpdate_ShouldNotDeleteStreamOnBadConfig() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerRedeliveredInfo_ShouldTrackRedeliveredCount() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerState_ShouldPreserveStateAfterLeaderChange() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterFullConsumerState_ShouldHandlePurgeWithActiveConsumer() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMetaSnapshotsAndCatchup_ShouldCatchupAfterRestart() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMetaSnapshotsMultiChange_ShouldHandleComplexDeltasOnRestart() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamSynchedTimeStamps_ShouldMaintainTimestampAfterLeaderChange() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterRestoreSingleConsumer_ShouldRestoreAfterFullClusterRestart() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMaxBytesForStream_ShouldEnforcePerServerStorageLimit() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamPublishWithActiveConsumers_ShouldDeliverInOrderAfterLeaderChange() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamOverlapSubjects_ShouldPreventOverlappingSubjects() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamInfoList_ShouldReturnCorrectMsgCountsForAllStreams() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerInfoList_ShouldReturnCorrectConsumerStates() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamUpdate_ShouldUpdateMaxMsgsSuccessfully() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamExtendedUpdates_ShouldAllowSubjectUpdateButNotMirrorChange() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterDoubleAdd_ShouldBeIdempotentForStreamsAndConsumers() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterDefaultMaxAckPending_ShouldSetDefaultAckPendingOnConsumer() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamNormalCatchup_ShouldCatchupAfterRejoiningCluster() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamSnapshotCatchup_ShouldCatchupViaSnapshotAfterRejoining() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterDeleteMsg_ShouldDeleteMessageAndSupportPurge() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterDeleteMsgAndRestart_ShouldSurviveFullRestart() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamSnapshotCatchupWithPurge_ShouldHandlePurgeDuringCatchup() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterExtendedStreamInfo_ShouldIncludeClusterInfoAndReplicas() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterExtendedStreamInfoSingleReplica_ShouldShowNoReplicasForR1Stream() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterInterestRetention_ShouldDeleteMsgsAfterAckWithInterestPolicy() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterWorkQueueRetention_ShouldRemoveMsgsAfterAckInWorkQueueMode() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMirrorAndSourceWorkQueues_ShouldMirrorWorkQueueMessages() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMirrorAndSourceInterestPolicyStream_ShouldHandleInterestPolicyWithMirrorAndSource() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterInterestRetentionWithFilteredConsumers_ShouldTrackPerFilteredConsumer() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterEphemeralConsumerNoImmediateInterest_ShouldCleanUpWithoutActiveSubscriber() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterEphemeralConsumerCleanup_ShouldRemoveConsumerOnUnsubscribe() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterEphemeralConsumersNotReplicated_ShouldBeR1Only() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterUserSnapshotAndRestore_ShouldRestoreStreamWithConsumerState() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterUserSnapshotAndRestoreConfigChanges_ShouldAllowConfigChangesOnRestore() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterAccountInfoAndLimits_ShouldEnforceStreamAndConsumerLimits() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMaxStreamsReached_ShouldAllowIdempotentCreateUnderLimit() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamLimits_ShouldEnforceMaxMsgSizeAndMaxMsgsAndMaxAge() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamInterestOnlyPolicy_ShouldNotRetainMsgsWithoutInterest() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterExtendedAccountInfo_ShouldTrackStreamsConsumersAndApiErrors() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterPeerRemovalApi_ShouldRemovePeerViaApi() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterPeerRemovalAndStreamReassignment_ShouldReassignStreamAfterPeerRemoval() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterPeerRemovalAndStreamReassignmentWithoutSpace_ShouldHandleInsufficientPeers() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterPeerRemovalAndServerBroughtBack_ShouldHandleServerReintroduction() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterPeerExclusionTag_ShouldExcludeTaggedPeersFromPlacement() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterAccountPurge_ShouldDeleteAllStreamsAndConsumersForAccount() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterScaleConsumer_ShouldScaleConsumerReplicasUpAndDown() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerScaleUp_ShouldMaintainConsumerLeadershipAfterStreamScaleUp() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterPeerOffline_ShouldMarkServerOfflineAndOnlineCorrectly() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterNoQuorumStepdown_ShouldStepDownLeaderWhenQuorumLost() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterCreateResponseAdvisoriesHaveSubject_ShouldIncludeSubjectInAdvisories() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterRestartAndRemoveAdvisories_ShouldNotSendAdvisoriesForRemovedOnRestart() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterNoDuplicateOnNodeRestart_ShouldNotDeliverDuplicateMessagesOnRestart() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterNoDupePeerSelection_ShouldNotSelectSamePeerTwiceForConsumer() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamRemovePeer_ShouldReassignStreamAfterPeerRemoval() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamLeaderStepDown_ShouldElectNewStreamLeaderAfterStepDown() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterRemoveServer_ShouldRebalanceStreamsAfterServerRemoval() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterPurgeReplayAfterRestart_ShouldReplayPurgeAfterRestart() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamGetMsg_ShouldGetMessageBySequenceFromCluster() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamDirectGetMsg_ShouldSupportDirectGetFromReplica() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamPerf_ShouldPublishAndReceiveAllMessagesWithinTimeout() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerPerf_ShouldDeliverAllMessagesToPushConsumer() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterQueueSubConsumer_ShouldDeliverExactlyOnceAcrossQueueGroup() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterLeaderStepdown_ShouldElectNewMetaLeaderAfterStepDown() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterSourcesFilteringAndUpdating_ShouldFilterSourcesBySubjectAndSupportUpdate() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterSourcesUpdateOriginError_ShouldReportErrorWhenSourceOriginChanges() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMirrorAndSourcesClusterRestart_ShouldContinueAfterRestart() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMirrorAndSourcesFilteredConsumers_ShouldWorkWithFilteredConsumers() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterCrossAccountMirrorsAndSources_ShouldMirrorAcrossAccounts() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterFailMirrorsAndSources_ShouldFailGracefullyOnInvalidMirrorOrSource() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerDeliveredSyncReporting_ShouldReportDeliveredSequenceAccurately() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerAckSyncReporting_ShouldReportAckFloorAccurately() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerDeleteInterestPolicyMultipleConsumers_ShouldNotPurgeMsgsWithOtherActiveConsumers() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerAckNoneInterestPolicyShouldNotRetainAfterDelivery_ShouldRemoveMsgsOnDelivery() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerDeleteAckNoneInterestPolicyWithOthers_ShouldHandleDeleteWithMultipleConsumers() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMetaStepdownFromNonSysAccount_ShouldFailWithPermissionError() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMaxDeliveriesOnInterestStreams_ShouldRespectMaxDeliveriesSetting() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMetaRecoveryUpdatesDeletesConsumers_ShouldRecoverUpdatedAndDeletedConsumers() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMetaRecoveryRecreateFileStreamAsMemory_ShouldRecoverStreamWithChangedStorageType() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMetaRecoveryConsumerCreateAndRemove_ShouldRecoverAfterConsumerCreateAndDelete() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterMetaRecoveryAddAndUpdateStream_ShouldRecoverUpdatedStreamConfig() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerAckOutOfBounds_ShouldHandleOutOfBoundsAckGracefully() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterCatchupLoadNextMsgTooManyDeletes_ShouldCatchupWithHighDensityDeletes() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterCatchupMustStallWhenBehindOnApplies_ShouldNotOverloadCatchupQueue() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerInfoAfterCreate_ShouldReturnConsumerInfoImmediatelyAfterCreate() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamUpscalePeersAfterDownscale_ShouldRestoreAllPeersOnUpscale() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterClearAllPreAcksOnRemoveMsg_ShouldClearPreAcksWhenMessageRemoved() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamHealthCheckMustNotRecreate_ShouldNotRecreateExistingStream() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamHealthCheckMustNotDeleteEarly_ShouldNotDeleteStreamDuringHealthCheck() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamHealthCheckOnlyReportsSkew_ShouldOnlyReportSkewNotForceRecovery() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStreamHealthCheckStreamCatchup_ShouldTriggerCatchupOnHealthCheckFailure() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerHealthCheckMustNotRecreate_ShouldNotRecreateExistingConsumer() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerHealthCheckMustNotDeleteEarly_ShouldNotDeleteActiveConsumer() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerHealthCheckOnlyReportsSkew_ShouldNotForceRecreateOnSkew() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerHealthCheckDeleted_ShouldCleanUpDeletedConsumerOnHealthCheck() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterRespectConsumerStartSeq_ShouldStartDeliveryFromConfiguredSequence() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterPeerRemoveStreamConsumerDesync_ShouldNotDesyncConsumerAfterPeerRemoval() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterStuckConsumerAfterLeaderChangeWithUnknownDeliveries_ShouldRecoverFromStuckState() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterAccountStatsForReplicatedStreams_ShouldCountStorageOnceNotPerReplica() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterRecreateConsumerFromMetaSnapshot_ShouldRecreateConsumerFromSnapshot() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterUpgradeStreamVersioning_ShouldHandleStreamVersionUpgrade() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterUpgradeConsumerVersioning_ShouldHandleConsumerVersionUpgrade() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterInterestPolicyAckAll_ShouldRemoveMsgOnlyAfterAllConsumersAckAll() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterPreserveRedeliveredWithLaggingStream_ShouldPreserveRedeliveredFlagDuringLag() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterInvalidJsAckOverRoute_ShouldHandleInvalidAckGracefully() { }
[Fact(Skip = "deferred: requires running JetStream cluster")]
public void ClusterConsumerOnlyDeliverMsgAfterQuorum_ShouldNotDeliverBeforeQuorumAchieved() { }
}