refactor: rename remaining tests to NATS.Server.Core.Tests
- Rename tests/NATS.Server.Tests -> tests/NATS.Server.Core.Tests - Update solution file, InternalsVisibleTo, and csproj references - Remove JETSTREAM_INTEGRATION_MATRIX and NATS.NKeys from csproj (moved to JetStream.Tests and Auth.Tests) - Update all namespaces from NATS.Server.Tests.* to NATS.Server.Core.Tests.* - Replace private GetFreePort/ReadUntilAsync helpers with TestUtilities calls - Fix stale namespace in Transport.Tests/NetworkingGoParityTests.cs
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
// Port of Go server/reload.go — auth change propagation tests.
|
||||
// Reference: golang/nats-server/server/reload.go — authOption.Apply, usersOption.Apply.
|
||||
|
||||
using NATS.Server.Auth;
|
||||
using NATS.Server.Configuration;
|
||||
using Shouldly;
|
||||
|
||||
namespace NATS.Server.Core.Tests.Configuration;
|
||||
|
||||
public sealed class AuthChangePropagationTests
|
||||
{
|
||||
// ─── helpers ────────────────────────────────────────────────────
|
||||
|
||||
private static User MakeUser(string username, string password = "pw") =>
|
||||
new() { Username = username, Password = password };
|
||||
|
||||
private static NatsOptions BaseOpts() => new();
|
||||
|
||||
// ─── tests ──────────────────────────────────────────────────────
|
||||
|
||||
[Fact]
|
||||
public void No_changes_returns_no_changes()
|
||||
{
|
||||
// Same empty options → nothing changed.
|
||||
var oldOpts = BaseOpts();
|
||||
var newOpts = BaseOpts();
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.HasChanges.ShouldBeFalse();
|
||||
result.UsersChanged.ShouldBeFalse();
|
||||
result.AccountsChanged.ShouldBeFalse();
|
||||
result.TokenChanged.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void User_added_detected()
|
||||
{
|
||||
// Adding a user must set UsersChanged.
|
||||
var oldOpts = BaseOpts();
|
||||
var newOpts = BaseOpts();
|
||||
newOpts.Users = [MakeUser("alice")];
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.UsersChanged.ShouldBeTrue();
|
||||
result.HasChanges.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void User_removed_detected()
|
||||
{
|
||||
// Removing a user must set UsersChanged.
|
||||
var oldOpts = BaseOpts();
|
||||
oldOpts.Users = [MakeUser("alice")];
|
||||
var newOpts = BaseOpts();
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.UsersChanged.ShouldBeTrue();
|
||||
result.HasChanges.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Account_added_detected()
|
||||
{
|
||||
// Adding an account must set AccountsChanged.
|
||||
var oldOpts = BaseOpts();
|
||||
var newOpts = BaseOpts();
|
||||
newOpts.Accounts = new Dictionary<string, AccountConfig>
|
||||
{
|
||||
["engineering"] = new AccountConfig()
|
||||
};
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.AccountsChanged.ShouldBeTrue();
|
||||
result.HasChanges.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Token_changed_detected()
|
||||
{
|
||||
// Changing the Authorization token must set TokenChanged.
|
||||
var oldOpts = BaseOpts();
|
||||
oldOpts.Authorization = "old-secret-token";
|
||||
var newOpts = BaseOpts();
|
||||
newOpts.Authorization = "new-secret-token";
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.TokenChanged.ShouldBeTrue();
|
||||
result.HasChanges.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiple_changes_all_flagged()
|
||||
{
|
||||
// Changing both users and accounts must set both flags.
|
||||
var oldOpts = BaseOpts();
|
||||
oldOpts.Users = [MakeUser("alice")];
|
||||
oldOpts.Accounts = new Dictionary<string, AccountConfig>
|
||||
{
|
||||
["acct-a"] = new AccountConfig()
|
||||
};
|
||||
|
||||
var newOpts = BaseOpts();
|
||||
newOpts.Users = [MakeUser("alice"), MakeUser("bob")];
|
||||
newOpts.Accounts = new Dictionary<string, AccountConfig>
|
||||
{
|
||||
["acct-a"] = new AccountConfig(),
|
||||
["acct-b"] = new AccountConfig()
|
||||
};
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.UsersChanged.ShouldBeTrue();
|
||||
result.AccountsChanged.ShouldBeTrue();
|
||||
result.HasChanges.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Same_users_different_order_no_change()
|
||||
{
|
||||
// Users in a different order with the same names must NOT trigger UsersChanged
|
||||
// because the comparison is set-based.
|
||||
var oldOpts = BaseOpts();
|
||||
oldOpts.Users = [MakeUser("alice"), MakeUser("bob")];
|
||||
|
||||
var newOpts = BaseOpts();
|
||||
newOpts.Users = [MakeUser("bob"), MakeUser("alice")];
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.UsersChanged.ShouldBeFalse();
|
||||
result.HasChanges.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasChanges_true_when_any_change()
|
||||
{
|
||||
// A single changed field (token only) is enough to set HasChanges.
|
||||
var oldOpts = BaseOpts();
|
||||
var newOpts = BaseOpts();
|
||||
newOpts.Authorization = "token-xyz";
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.HasChanges.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Empty_to_non_empty_users_detected()
|
||||
{
|
||||
// Going from zero users to one user must be detected.
|
||||
var oldOpts = BaseOpts();
|
||||
// No Users assigned — null list.
|
||||
var newOpts = BaseOpts();
|
||||
newOpts.Users = [MakeUser("charlie")];
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.UsersChanged.ShouldBeTrue();
|
||||
result.HasChanges.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void No_auth_to_auth_detected()
|
||||
{
|
||||
// Going from null Authorization to a token string must be detected.
|
||||
var oldOpts = BaseOpts();
|
||||
// Authorization is null by default.
|
||||
var newOpts = BaseOpts();
|
||||
newOpts.Authorization = "brand-new-token";
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.TokenChanged.ShouldBeTrue();
|
||||
result.HasChanges.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Same_token_no_change()
|
||||
{
|
||||
// The same token value on both sides must NOT flag TokenChanged.
|
||||
var oldOpts = BaseOpts();
|
||||
oldOpts.Authorization = "stable-token";
|
||||
var newOpts = BaseOpts();
|
||||
newOpts.Authorization = "stable-token";
|
||||
|
||||
var result = ConfigReloader.PropagateAuthChanges(oldOpts, newOpts);
|
||||
|
||||
result.TokenChanged.ShouldBeFalse();
|
||||
result.HasChanges.ShouldBeFalse();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user