using Akka.Actor;
using Akka.Configuration;
using Shouldly;
using Xunit;
namespace ZB.MOM.WW.OtOpcUa.Cluster.Tests;
///
/// Asserts the remoting frame-size canary and the DistributedPubSub extension that are actually
/// in force on a real built from the shipped base config.
///
///
/// Asserting the akka.conf text instead would pass while a competing HOCON fragment
/// silently overrode the value — the failure mode recorded at length in
/// ServiceCollectionExtensions.BuildDowningHocon and pinned the same way by
/// SplitBrainResolverActivationTests. In this codebase the effective value is the only
/// one worth asserting.
///
public class MeshTransportHoconTests : IDisposable
{
private readonly ActorSystem _sys;
public MeshTransportHoconTests()
{
var config = ConfigurationFactory
.ParseString("akka.remote.dot-netty.tcp.port = 0\nakka.cluster.seed-nodes = []")
.WithFallback(HoconLoader.LoadBaseConfig());
_sys = ActorSystem.Create("mesh-hocon-probe", config);
}
[Fact]
public void Oversized_frames_are_logged_rather_than_dropped_silently()
{
// The sister project's most expensive incident. A message over the frame limit is dropped
// WITHOUT tearing down the association: heartbeats keep flowing, the node still reports
// healthy, and the only symptom is a command that never arrived. log-frame-size-exceeding
// converts that silence into a log line naming the offending size.
_sys.Settings.Config.GetByteSize("akka.remote.dot-netty.tcp.maximum-frame-size").ShouldBe(128000);
_sys.Settings.Config.GetByteSize("akka.remote.dot-netty.tcp.log-frame-size-exceeding").ShouldBe(32000);
}
[Fact]
public void Distributed_pub_sub_extension_is_registered_at_startup()
{
// DPS is PAIR-LOCAL and survives the cross-mesh transport's deletion: it carries
// MeshTransport:Mode = Dps (the single-mesh default), the node-local alarm-command publishes
// and the node<->node redundancy-state probe leg. Losing it would break far more than deploys.
_sys.Settings.Config.GetStringList("akka.extensions")
.ShouldContain(s => s.Contains("DistributedPubSubExtensionProvider"));
}
public void Dispose()
{
_sys.Terminate().Wait(TimeSpan.FromSeconds(5));
GC.SuppressFinalize(this);
}
}