diff --git a/tests/NATS.Server.Tests/ConfigProcessorTests.cs b/tests/NATS.Server.Tests/ConfigProcessorTests.cs index 0ee2f39..6f7a7e5 100644 --- a/tests/NATS.Server.Tests/ConfigProcessorTests.cs +++ b/tests/NATS.Server.Tests/ConfigProcessorTests.cs @@ -501,4 +501,112 @@ public class ConfigProcessorTests var opts = ConfigProcessor.ProcessConfigFile(TestDataPath("tls.conf")); opts.HasTls.ShouldBeTrue(); } + + // ─── MQTT config ──────────────────────────────────────────── + + [Fact] + public void MqttConf_ListenHostAndPort() + { + var opts = ConfigProcessor.ProcessConfigFile(TestDataPath("mqtt.conf")); + opts.Mqtt.ShouldNotBeNull(); + opts.Mqtt!.Host.ShouldBe("10.0.0.1"); + opts.Mqtt.Port.ShouldBe(1883); + } + + [Fact] + public void MqttConf_NoAuthUser() + { + var opts = ConfigProcessor.ProcessConfigFile(TestDataPath("mqtt.conf")); + opts.Mqtt.ShouldNotBeNull(); + opts.Mqtt!.NoAuthUser.ShouldBe("mqtt_default"); + } + + [Fact] + public void MqttConf_Authorization() + { + var opts = ConfigProcessor.ProcessConfigFile(TestDataPath("mqtt.conf")); + opts.Mqtt.ShouldNotBeNull(); + opts.Mqtt!.Username.ShouldBe("mqtt_user"); + opts.Mqtt.Password.ShouldBe("mqtt_pass"); + opts.Mqtt.Token.ShouldBe("mqtt_token"); + opts.Mqtt.AuthTimeout.ShouldBe(3.0); + } + + [Fact] + public void MqttConf_Tls() + { + var opts = ConfigProcessor.ProcessConfigFile(TestDataPath("mqtt.conf")); + opts.Mqtt.ShouldNotBeNull(); + opts.Mqtt!.TlsCert.ShouldBe("/path/to/mqtt-cert.pem"); + opts.Mqtt.TlsKey.ShouldBe("/path/to/mqtt-key.pem"); + opts.Mqtt.TlsCaCert.ShouldBe("/path/to/mqtt-ca.pem"); + opts.Mqtt.TlsVerify.ShouldBeTrue(); + opts.Mqtt.TlsTimeout.ShouldBe(5.0); + opts.Mqtt.HasTls.ShouldBeTrue(); + } + + [Fact] + public void MqttConf_QosSettings() + { + var opts = ConfigProcessor.ProcessConfigFile(TestDataPath("mqtt.conf")); + opts.Mqtt.ShouldNotBeNull(); + opts.Mqtt!.AckWait.ShouldBe(TimeSpan.FromSeconds(60)); + opts.Mqtt.MaxAckPending.ShouldBe((ushort)2048); + opts.Mqtt.JsApiTimeout.ShouldBe(TimeSpan.FromSeconds(10)); + } + + [Fact] + public void MqttConf_JetStreamSettings() + { + var opts = ConfigProcessor.ProcessConfigFile(TestDataPath("mqtt.conf")); + opts.Mqtt.ShouldNotBeNull(); + opts.Mqtt!.JsDomain.ShouldBe("mqtt-domain"); + opts.Mqtt.StreamReplicas.ShouldBe(3); + opts.Mqtt.ConsumerReplicas.ShouldBe(1); + opts.Mqtt.ConsumerMemoryStorage.ShouldBeTrue(); + opts.Mqtt.ConsumerInactiveThreshold.ShouldBe(TimeSpan.FromMinutes(5)); + } + + [Fact] + public void MqttConf_MaxAckPendingValidation_ReportsError() + { + var ex = Should.Throw(() => + ConfigProcessor.ProcessConfig(""" + mqtt { + max_ack_pending: 70000 + } + """)); + ex.Errors.ShouldContain(e => e.Contains("max_ack_pending")); + } + + [Fact] + public void MqttConf_Aliases() + { + // Test alias keys: "ackwait" (alias for "ack_wait"), "net" (alias for "host"), + // "max_inflight" (alias for "max_ack_pending"), "consumer_auto_cleanup" (alias) + var opts = ConfigProcessor.ProcessConfig(""" + mqtt { + net: "127.0.0.1" + port: 1884 + ackwait: "45s" + max_inflight: 500 + api_timeout: "8s" + consumer_auto_cleanup: "10m" + } + """); + opts.Mqtt.ShouldNotBeNull(); + opts.Mqtt!.Host.ShouldBe("127.0.0.1"); + opts.Mqtt.Port.ShouldBe(1884); + opts.Mqtt.AckWait.ShouldBe(TimeSpan.FromSeconds(45)); + opts.Mqtt.MaxAckPending.ShouldBe((ushort)500); + opts.Mqtt.JsApiTimeout.ShouldBe(TimeSpan.FromSeconds(8)); + opts.Mqtt.ConsumerInactiveThreshold.ShouldBe(TimeSpan.FromMinutes(10)); + } + + [Fact] + public void MqttConf_Absent_ReturnsNull() + { + var opts = ConfigProcessor.ProcessConfig("port: 4222"); + opts.Mqtt.ShouldBeNull(); + } } diff --git a/tests/NATS.Server.Tests/TestData/mqtt.conf b/tests/NATS.Server.Tests/TestData/mqtt.conf new file mode 100644 index 0000000..e0692fa --- /dev/null +++ b/tests/NATS.Server.Tests/TestData/mqtt.conf @@ -0,0 +1,28 @@ +mqtt { + listen: "10.0.0.1:1883" + no_auth_user: "mqtt_default" + + authorization { + user: "mqtt_user" + pass: "mqtt_pass" + token: "mqtt_token" + timeout: 3.0 + } + + tls { + cert_file: "/path/to/mqtt-cert.pem" + key_file: "/path/to/mqtt-key.pem" + ca_file: "/path/to/mqtt-ca.pem" + verify: true + timeout: 5.0 + } + + ack_wait: "60s" + max_ack_pending: 2048 + js_domain: "mqtt-domain" + js_api_timeout: "10s" + stream_replicas: 3 + consumer_replicas: 1 + consumer_memory_storage: true + consumer_inactive_threshold: "5m" +}