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:
184
tests/NATS.Server.Core.Tests/NatsConfParserTests.cs
Normal file
184
tests/NATS.Server.Core.Tests/NatsConfParserTests.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using NATS.Server.Configuration;
|
||||
|
||||
namespace NATS.Server.Core.Tests;
|
||||
|
||||
public class NatsConfParserTests
|
||||
{
|
||||
[Fact]
|
||||
public void Parse_SimpleTopLevel_ReturnsCorrectTypes()
|
||||
{
|
||||
var result = NatsConfParser.Parse("foo = '1'; bar = 2.2; baz = true; boo = 22");
|
||||
result["foo"].ShouldBe("1");
|
||||
result["bar"].ShouldBe(2.2);
|
||||
result["baz"].ShouldBe(true);
|
||||
result["boo"].ShouldBe(22L);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Booleans_AllVariants()
|
||||
{
|
||||
foreach (var (input, expected) in new[] {
|
||||
("true", true), ("TRUE", true), ("yes", true), ("on", true),
|
||||
("false", false), ("FALSE", false), ("no", false), ("off", false)
|
||||
})
|
||||
{
|
||||
var result = NatsConfParser.Parse($"flag = {input}");
|
||||
result["flag"].ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_IntegerWithSuffix_AppliesMultiplier()
|
||||
{
|
||||
var result = NatsConfParser.Parse("a = 1k; b = 2mb; c = 3gb; d = 4kb");
|
||||
result["a"].ShouldBe(1000L);
|
||||
result["b"].ShouldBe(2L * 1024 * 1024);
|
||||
result["c"].ShouldBe(3L * 1024 * 1024 * 1024);
|
||||
result["d"].ShouldBe(4L * 1024);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_NestedMap_ReturnsDictionary()
|
||||
{
|
||||
var result = NatsConfParser.Parse("auth { user: admin, pass: secret }");
|
||||
var auth = result["auth"].ShouldBeOfType<Dictionary<string, object?>>();
|
||||
auth["user"].ShouldBe("admin");
|
||||
auth["pass"].ShouldBe("secret");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Array_ReturnsList()
|
||||
{
|
||||
var result = NatsConfParser.Parse("items = [1, 2, 3]");
|
||||
var items = result["items"].ShouldBeOfType<List<object?>>();
|
||||
items.Count.ShouldBe(3);
|
||||
items[0].ShouldBe(1L);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Variable_ResolvesFromContext()
|
||||
{
|
||||
var result = NatsConfParser.Parse("index = 22\nfoo = $index");
|
||||
result["foo"].ShouldBe(22L);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_NestedVariable_UsesBlockScope()
|
||||
{
|
||||
var input = "index = 22\nnest {\n index = 11\n foo = $index\n}\nbar = $index";
|
||||
var result = NatsConfParser.Parse(input);
|
||||
var nest = result["nest"].ShouldBeOfType<Dictionary<string, object?>>();
|
||||
nest["foo"].ShouldBe(11L);
|
||||
result["bar"].ShouldBe(22L);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_EnvironmentVariable_ResolvesFromEnv()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("NATS_TEST_VAR_12345", "hello");
|
||||
try
|
||||
{
|
||||
var result = NatsConfParser.Parse("val = $NATS_TEST_VAR_12345");
|
||||
result["val"].ShouldBe("hello");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Environment.SetEnvironmentVariable("NATS_TEST_VAR_12345", null);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_UndefinedVariable_Throws()
|
||||
{
|
||||
Should.Throw<FormatException>(() =>
|
||||
NatsConfParser.Parse("val = $UNDEFINED_VAR_XYZZY_99999"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_IncludeDirective_MergesFile()
|
||||
{
|
||||
var dir = Path.Combine(Path.GetTempPath(), $"nats_test_{Guid.NewGuid():N}");
|
||||
Directory.CreateDirectory(dir);
|
||||
try
|
||||
{
|
||||
File.WriteAllText(Path.Combine(dir, "main.conf"), "port = 4222\ninclude \"sub.conf\"");
|
||||
File.WriteAllText(Path.Combine(dir, "sub.conf"), "host = \"localhost\"");
|
||||
var result = NatsConfParser.ParseFile(Path.Combine(dir, "main.conf"));
|
||||
result["port"].ShouldBe(4222L);
|
||||
result["host"].ShouldBe("localhost");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(dir, true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_MultipleKeySeparators_AllWork()
|
||||
{
|
||||
var r1 = NatsConfParser.Parse("a = 1");
|
||||
var r2 = NatsConfParser.Parse("a : 1");
|
||||
var r3 = NatsConfParser.Parse("a 1");
|
||||
r1["a"].ShouldBe(1L);
|
||||
r2["a"].ShouldBe(1L);
|
||||
r3["a"].ShouldBe(1L);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_ErrorOnInvalidInput_Throws()
|
||||
{
|
||||
Should.Throw<FormatException>(() => NatsConfParser.Parse("= invalid"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_CommentsInsideBlocks_AreIgnored()
|
||||
{
|
||||
var input = "auth {\n # comment\n user: admin\n // another comment\n pass: secret\n}";
|
||||
var result = NatsConfParser.Parse(input);
|
||||
var auth = result["auth"].ShouldBeOfType<Dictionary<string, object?>>();
|
||||
auth["user"].ShouldBe("admin");
|
||||
auth["pass"].ShouldBe("secret");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_ArrayOfMaps_Works()
|
||||
{
|
||||
var input = "users = [\n { user: alice, pass: pw1 }\n { user: bob, pass: pw2 }\n]";
|
||||
var result = NatsConfParser.Parse(input);
|
||||
var users = result["users"].ShouldBeOfType<List<object?>>();
|
||||
users.Count.ShouldBe(2);
|
||||
var first = users[0].ShouldBeOfType<Dictionary<string, object?>>();
|
||||
first["user"].ShouldBe("alice");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_BcryptPassword_HandledAsString()
|
||||
{
|
||||
var input = "pass = $2a$04$P/.bd.7unw9Ew7yWJqXsl.f4oNRLQGvadEL2YnqQXbbb.IVQajRdK";
|
||||
var result = NatsConfParser.Parse(input);
|
||||
((string)result["pass"]!).ShouldStartWith("$2a$");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseFile_WithDigest_ReturnsStableHash()
|
||||
{
|
||||
var dir = Path.Combine(Path.GetTempPath(), $"nats_test_{Guid.NewGuid():N}");
|
||||
Directory.CreateDirectory(dir);
|
||||
try
|
||||
{
|
||||
var conf = Path.Combine(dir, "test.conf");
|
||||
File.WriteAllText(conf, "port = 4222\nhost = \"localhost\"");
|
||||
var (result, digest) = NatsConfParser.ParseFileWithDigest(conf);
|
||||
result["port"].ShouldBe(4222L);
|
||||
digest.ShouldStartWith("sha256:");
|
||||
digest.Length.ShouldBeGreaterThan(10);
|
||||
|
||||
var (_, digest2) = NatsConfParser.ParseFileWithDigest(conf);
|
||||
digest2.ShouldBe(digest);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(dir, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user