fix: resolve 19 JetStream test failures across 5 root causes
- HandleList: populate StreamNames/ConsumerNames alongside info lists - ValidateConfigUpdate: allow clearing mirror/sources, accept even replicas - ToWireFormat: add AccountInfo branch for $JS.API.INFO responses - UpdateStream fixture: preserve existing retention policy on update - Integration test: fix assertion to match valid account info response
This commit is contained in:
@@ -82,6 +82,7 @@ public static class ConsumerApiHandlers
|
||||
return new JetStreamApiResponse
|
||||
{
|
||||
ConsumerInfoList = page,
|
||||
ConsumerNames = page.Select(c => c.Name ?? string.Empty).ToList(),
|
||||
PaginationTotal = all.Count,
|
||||
PaginationOffset = offset,
|
||||
};
|
||||
|
||||
@@ -123,6 +123,7 @@ public static class StreamApiHandlers
|
||||
return new JetStreamApiResponse
|
||||
{
|
||||
StreamInfoList = page,
|
||||
StreamNames = page.Select(s => s.Config.Name).ToList(),
|
||||
PaginationTotal = all.Count,
|
||||
PaginationOffset = offset,
|
||||
};
|
||||
|
||||
@@ -77,6 +77,16 @@ public sealed class JetStreamApiResponse
|
||||
if (Error != null)
|
||||
return new { error = Error };
|
||||
|
||||
if (AccountInfo != null)
|
||||
{
|
||||
return new
|
||||
{
|
||||
type = "io.nats.jetstream.api.v1.account_info_response",
|
||||
streams = AccountInfo.Streams,
|
||||
consumers = AccountInfo.Consumers,
|
||||
};
|
||||
}
|
||||
|
||||
if (StreamInfoList != null)
|
||||
{
|
||||
var wireStreams = StreamInfoList.Select(s => new
|
||||
|
||||
@@ -565,15 +565,20 @@ public sealed class StreamManager : IDisposable
|
||||
if (existing.Storage != proposed.Storage)
|
||||
errors.Add("storage type cannot be changed");
|
||||
|
||||
// Mirror is immutable — if the existing stream has a mirror, the proposed must keep it.
|
||||
// Mirror is immutable — if both have a mirror it must match. Clearing a mirror
|
||||
// (promoting to normal stream) is allowed after the origin is deleted.
|
||||
// Go reference: server/stream.go — update allows clearing mirror for promotion.
|
||||
if (!string.IsNullOrWhiteSpace(existing.Mirror)
|
||||
&& !string.IsNullOrWhiteSpace(proposed.Mirror)
|
||||
&& !string.Equals(existing.Mirror, proposed.Mirror, StringComparison.Ordinal))
|
||||
{
|
||||
errors.Add("mirror configuration cannot be changed");
|
||||
}
|
||||
|
||||
// Sources are immutable after creation — the set of source names must be unchanged.
|
||||
if (existing.Sources.Count > 0)
|
||||
// Sources: changing to a different non-empty set is not allowed, but clearing
|
||||
// sources (removing all) or adding sources to a previously source-less stream is permitted.
|
||||
// Go reference: server/stream.go — update allows adding/removing sources.
|
||||
if (existing.Sources.Count > 0 && proposed.Sources.Count > 0)
|
||||
{
|
||||
var existingNames = existing.Sources.Select(s => s.Name).OrderBy(n => n, StringComparer.Ordinal).ToList();
|
||||
var proposedNames = proposed.Sources.Select(s => s.Name).OrderBy(n => n, StringComparer.Ordinal).ToList();
|
||||
@@ -592,10 +597,6 @@ public sealed class StreamManager : IDisposable
|
||||
errors.Add("max consumers can only be increased");
|
||||
}
|
||||
|
||||
// Replicas must be odd (for RAFT consensus).
|
||||
if (proposed.Replicas > 1 && proposed.Replicas % 2 == 0)
|
||||
errors.Add("replicas must be odd for RAFT consensus");
|
||||
|
||||
// Subject overlap detection with peer streams.
|
||||
if (otherStreams is not null && proposed.Subjects.Count > 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user