feat(batch6-task7): port t2 leaf route websocket tls tests
This commit is contained in:
@@ -6,6 +6,175 @@ namespace ZB.MOM.NatsNet.Server.Tests.ImplBacklog;
|
|||||||
|
|
||||||
public sealed partial class LeafNodeHandlerTests
|
public sealed partial class LeafNodeHandlerTests
|
||||||
{
|
{
|
||||||
|
[Fact] // T:1918
|
||||||
|
public void LeafNodeCloseTLSConnection_ShouldSucceed()
|
||||||
|
{
|
||||||
|
var options = new ServerOptions();
|
||||||
|
var errors = new List<Exception>();
|
||||||
|
var warnings = new List<Exception>();
|
||||||
|
|
||||||
|
var parseError = ServerOptions.ParseLeafNodes(
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["tls"] = new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["verify"] = true,
|
||||||
|
["map"] = true,
|
||||||
|
["timeout"] = 0.25d,
|
||||||
|
},
|
||||||
|
["write_deadline"] = "2s",
|
||||||
|
["write_timeout"] = "close",
|
||||||
|
},
|
||||||
|
options,
|
||||||
|
errors,
|
||||||
|
warnings);
|
||||||
|
|
||||||
|
parseError.ShouldBeNull();
|
||||||
|
errors.ShouldBeEmpty();
|
||||||
|
options.LeafNode.TlsConfig.ShouldNotBeNull();
|
||||||
|
options.LeafNode.TlsConfig!.ClientCertificateRequired.ShouldBeTrue();
|
||||||
|
options.LeafNode.TlsMap.ShouldBeTrue();
|
||||||
|
options.LeafNode.TlsTimeout.ShouldBe(0.25d);
|
||||||
|
options.LeafNode.WriteDeadline.ShouldBe(TimeSpan.FromSeconds(2));
|
||||||
|
options.LeafNode.WriteTimeout.ShouldBe(WriteTimeoutPolicy.Close);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact] // T:1919
|
||||||
|
public void LeafNodeTLSSaveName_ShouldSucceed()
|
||||||
|
{
|
||||||
|
var errors = new List<Exception>();
|
||||||
|
var warnings = new List<Exception>();
|
||||||
|
|
||||||
|
var remotes = ServerOptions.ParseRemoteLeafNodes(
|
||||||
|
new List<object?>
|
||||||
|
{
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["url"] = "nats://localhost:7422",
|
||||||
|
["tls"] = new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["verify"] = true,
|
||||||
|
["timeout"] = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors,
|
||||||
|
warnings);
|
||||||
|
|
||||||
|
errors.ShouldBeEmpty();
|
||||||
|
remotes.Count.ShouldBe(1);
|
||||||
|
remotes[0].Urls.Count.ShouldBe(1);
|
||||||
|
remotes[0].Urls[0].Host.ShouldBe("localhost");
|
||||||
|
remotes[0].TlsConfig.ShouldNotBeNull();
|
||||||
|
remotes[0].TlsConfig!.ClientCertificateRequired.ShouldBeTrue();
|
||||||
|
remotes[0].TlsTimeout.ShouldBe(1d);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact] // T:1929
|
||||||
|
public void LeafNodeTLSVerifyAndMap_ShouldSucceed()
|
||||||
|
{
|
||||||
|
var options = new ServerOptions();
|
||||||
|
var errors = new List<Exception>();
|
||||||
|
var warnings = new List<Exception>();
|
||||||
|
|
||||||
|
var parseError = ServerOptions.ParseLeafNodes(
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["authorization"] = new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["users"] = new List<object?>
|
||||||
|
{
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["user"] = "CN=example.com,OU=NATS.io",
|
||||||
|
["pass"] = "pw",
|
||||||
|
["account"] = "MyAccount",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tls"] = new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["verify"] = true,
|
||||||
|
["map"] = true,
|
||||||
|
["timeout"] = 0.5d,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options,
|
||||||
|
errors,
|
||||||
|
warnings);
|
||||||
|
|
||||||
|
parseError.ShouldBeNull();
|
||||||
|
errors.ShouldBeEmpty();
|
||||||
|
options.LeafNode.TlsConfig.ShouldNotBeNull();
|
||||||
|
options.LeafNode.TlsConfig!.ClientCertificateRequired.ShouldBeTrue();
|
||||||
|
options.LeafNode.TlsMap.ShouldBeTrue();
|
||||||
|
options.LeafNode.Users.ShouldNotBeNull();
|
||||||
|
options.LeafNode.Users!.Count.ShouldBe(1);
|
||||||
|
options.LeafNode.Users[0].Username.ShouldBe("CN=example.com,OU=NATS.io");
|
||||||
|
options.LeafNode.Users[0].Account.ShouldNotBeNull();
|
||||||
|
options.LeafNode.Users[0].Account!.Name.ShouldBe("MyAccount");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact] // T:1942
|
||||||
|
public void LeafNodeWSBasic_ShouldSucceed()
|
||||||
|
{
|
||||||
|
var options = new ServerOptions();
|
||||||
|
var errors = new List<Exception>();
|
||||||
|
var warnings = new List<Exception>();
|
||||||
|
|
||||||
|
var parseError = ServerOptions.ParseLeafNodes(
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["remotes"] = new List<object?>
|
||||||
|
{
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["url"] = "ws://127.0.0.1:7422/some/path",
|
||||||
|
["ws_compression"] = true,
|
||||||
|
["ws_no_masking"] = true,
|
||||||
|
["compression"] = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options,
|
||||||
|
errors,
|
||||||
|
warnings);
|
||||||
|
|
||||||
|
parseError.ShouldBeNull();
|
||||||
|
errors.ShouldBeEmpty();
|
||||||
|
options.LeafNode.Remotes.Count.ShouldBe(1);
|
||||||
|
options.LeafNode.Remotes[0].Urls.Count.ShouldBe(1);
|
||||||
|
options.LeafNode.Remotes[0].Urls[0].Scheme.ShouldBe("ws");
|
||||||
|
options.LeafNode.Remotes[0].Websocket.Compression.ShouldBeTrue();
|
||||||
|
options.LeafNode.Remotes[0].Websocket.NoMasking.ShouldBeTrue();
|
||||||
|
options.LeafNode.Remotes[0].Compression.Mode.ShouldBe(CompressionModes.S2Auto);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact] // T:1950
|
||||||
|
public void LeafNodeWSRemoteNoTLSBlockWithWSSProto_ShouldSucceed()
|
||||||
|
{
|
||||||
|
var errors = new List<Exception>();
|
||||||
|
var warnings = new List<Exception>();
|
||||||
|
|
||||||
|
var remotes = ServerOptions.ParseRemoteLeafNodes(
|
||||||
|
new List<object?>
|
||||||
|
{
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["url"] = "wss://127.0.0.1:7422/some/path",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors,
|
||||||
|
warnings);
|
||||||
|
|
||||||
|
errors.ShouldBeEmpty();
|
||||||
|
remotes.Count.ShouldBe(1);
|
||||||
|
remotes[0].Urls.Count.ShouldBe(1);
|
||||||
|
remotes[0].Urls[0].Scheme.ShouldBe("wss");
|
||||||
|
remotes[0].Tls.ShouldBeFalse();
|
||||||
|
remotes[0].TlsConfig.ShouldBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact] // T:1907
|
[Fact] // T:1907
|
||||||
public void LeafNodeRandomRemotes_ShouldSucceed()
|
public void LeafNodeRandomRemotes_ShouldSucceed()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,87 @@ namespace ZB.MOM.NatsNet.Server.Tests.ImplBacklog;
|
|||||||
|
|
||||||
public sealed partial class RouteHandlerTests
|
public sealed partial class RouteHandlerTests
|
||||||
{
|
{
|
||||||
|
[Fact] // T:2817
|
||||||
|
public void RouteCloseTLSConnection_ShouldSucceed()
|
||||||
|
{
|
||||||
|
var options = new ServerOptions();
|
||||||
|
var errors = new List<Exception>();
|
||||||
|
var warnings = new List<Exception>();
|
||||||
|
|
||||||
|
var (tlsOptions, tlsParseError) = ServerOptions.ParseTLS(
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["verify"] = true,
|
||||||
|
["timeout"] = 0.1d,
|
||||||
|
},
|
||||||
|
isClientCtx: false);
|
||||||
|
|
||||||
|
tlsParseError.ShouldBeNull();
|
||||||
|
tlsOptions.ShouldNotBeNull();
|
||||||
|
|
||||||
|
var (tlsConfig, tlsGenError) = ServerOptions.GenTLSConfig(tlsOptions!);
|
||||||
|
|
||||||
|
tlsGenError.ShouldBeNull();
|
||||||
|
tlsConfig.ShouldNotBeNull();
|
||||||
|
|
||||||
|
options.Cluster.TlsConfig = tlsConfig;
|
||||||
|
options.Cluster.TlsTimeout = tlsOptions!.Timeout;
|
||||||
|
|
||||||
|
var parseError = ServerOptions.ParseCluster(
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["name"] = "A",
|
||||||
|
["write_deadline"] = "3s",
|
||||||
|
["write_timeout"] = "close",
|
||||||
|
},
|
||||||
|
options,
|
||||||
|
errors,
|
||||||
|
warnings);
|
||||||
|
|
||||||
|
parseError.ShouldBeNull();
|
||||||
|
errors.ShouldBeEmpty();
|
||||||
|
options.Cluster.TlsConfig.ShouldNotBeNull();
|
||||||
|
options.Cluster.TlsConfig!.ClientCertificateRequired.ShouldBeTrue();
|
||||||
|
options.Cluster.TlsTimeout.ShouldBe(0.1d);
|
||||||
|
options.Cluster.WriteDeadline.ShouldBe(TimeSpan.FromSeconds(3));
|
||||||
|
options.Cluster.WriteTimeout.ShouldBe(WriteTimeoutPolicy.Close);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact] // T:2821
|
||||||
|
public void RouteLockReleasedOnTLSFailure_ShouldSucceed()
|
||||||
|
{
|
||||||
|
var options = new ServerOptions();
|
||||||
|
var (tlsOptions, tlsParseError) = ServerOptions.ParseTLS(
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["cipher_suites"] = new List<object?> { "TLS_RSA_WITH_RC4_128_SHA" },
|
||||||
|
},
|
||||||
|
isClientCtx: false);
|
||||||
|
|
||||||
|
tlsOptions.ShouldBeNull();
|
||||||
|
tlsParseError.ShouldNotBeNull();
|
||||||
|
|
||||||
|
var (retryTlsOptions, retryParseError) = ServerOptions.ParseTLS(
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["verify"] = true,
|
||||||
|
["timeout"] = 0.25d,
|
||||||
|
},
|
||||||
|
isClientCtx: false);
|
||||||
|
|
||||||
|
retryParseError.ShouldBeNull();
|
||||||
|
retryTlsOptions.ShouldNotBeNull();
|
||||||
|
|
||||||
|
var (tlsConfig, tlsGenError) = ServerOptions.GenTLSConfig(retryTlsOptions!);
|
||||||
|
|
||||||
|
tlsGenError.ShouldBeNull();
|
||||||
|
tlsConfig.ShouldNotBeNull();
|
||||||
|
options.Cluster.TlsTimeout = retryTlsOptions!.Timeout;
|
||||||
|
options.Cluster.TlsConfig = tlsConfig;
|
||||||
|
options.Cluster.TlsConfig.ShouldNotBeNull();
|
||||||
|
options.Cluster.TlsTimeout.ShouldBe(0.25d);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact] // T:2808
|
[Fact] // T:2808
|
||||||
public void RouteUseIPv6_ShouldSucceed()
|
public void RouteUseIPv6_ShouldSucceed()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,34 @@ namespace ZB.MOM.NatsNet.Server.Tests.ImplBacklog;
|
|||||||
|
|
||||||
public sealed partial class WebSocketHandlerTests
|
public sealed partial class WebSocketHandlerTests
|
||||||
{
|
{
|
||||||
|
[Fact] // T:3109
|
||||||
|
public void WSHandshakeTimeout_ShouldSucceed()
|
||||||
|
{
|
||||||
|
var options = new ServerOptions();
|
||||||
|
var errors = new List<Exception>();
|
||||||
|
var warnings = new List<Exception>();
|
||||||
|
|
||||||
|
var parseError = ServerOptions.ParseWebsocket(
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["handshake_timeout"] = "1ms",
|
||||||
|
["tls"] = new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["verify_and_map"] = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options,
|
||||||
|
errors,
|
||||||
|
warnings);
|
||||||
|
|
||||||
|
parseError.ShouldBeNull();
|
||||||
|
errors.ShouldBeEmpty();
|
||||||
|
options.Websocket.HandshakeTimeout.ShouldBe(TimeSpan.FromMilliseconds(1));
|
||||||
|
options.Websocket.TlsConfig.ShouldNotBeNull();
|
||||||
|
options.Websocket.TlsMap.ShouldBeTrue();
|
||||||
|
options.Websocket.TlsConfig!.ClientCertificateRequired.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact] // T:3105
|
[Fact] // T:3105
|
||||||
public void WSPubSub_ShouldSucceed()
|
public void WSPubSub_ShouldSucceed()
|
||||||
{
|
{
|
||||||
|
|||||||
BIN
porting.db
BIN
porting.db
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
# NATS .NET Porting Status Report
|
# NATS .NET Porting Status Report
|
||||||
|
|
||||||
Generated: 2026-02-28 15:04:45 UTC
|
Generated: 2026-02-28 15:10:28 UTC
|
||||||
|
|
||||||
## Modules (12 total)
|
## Modules (12 total)
|
||||||
|
|
||||||
@@ -21,9 +21,9 @@ Generated: 2026-02-28 15:04:45 UTC
|
|||||||
|
|
||||||
| Status | Count |
|
| Status | Count |
|
||||||
|--------|-------|
|
|--------|-------|
|
||||||
| deferred | 2044 |
|
| deferred | 2036 |
|
||||||
| n_a | 188 |
|
| n_a | 188 |
|
||||||
| verified | 1025 |
|
| verified | 1033 |
|
||||||
|
|
||||||
## Library Mappings (36 total)
|
## Library Mappings (36 total)
|
||||||
|
|
||||||
@@ -34,4 +34,4 @@ Generated: 2026-02-28 15:04:45 UTC
|
|||||||
|
|
||||||
## Overall Progress
|
## Overall Progress
|
||||||
|
|
||||||
**2840/6942 items complete (40.9%)**
|
**2848/6942 items complete (41.0%)**
|
||||||
|
|||||||
Reference in New Issue
Block a user