Reformat/cleanup
All checks were successful
NuGet Package Publish / nuget (push) Successful in 1m10s

This commit is contained in:
Joseph Doherty
2026-02-21 07:53:53 -05:00
parent c6f6d9329a
commit 7ebc2cb567
160 changed files with 7258 additions and 7262 deletions

View File

@@ -1,17 +1,13 @@
using ZB.MOM.WW.CBDDC.Core;
using System.Linq;
using Xunit;
namespace ZB.MOM.WW.CBDDC.Core.Tests;
public class VectorClockTests
{
/// <summary>
/// Verifies an empty vector clock returns the default timestamp for unknown nodes.
/// </summary>
[Fact]
public void EmptyVectorClock_ShouldReturnDefaultTimestamp()
{
public class VectorClockTests
{
/// <summary>
/// Verifies an empty vector clock returns the default timestamp for unknown nodes.
/// </summary>
[Fact]
public void EmptyVectorClock_ShouldReturnDefaultTimestamp()
{
// Arrange
var vc = new VectorClock();
@@ -19,15 +15,15 @@ public class VectorClockTests
var ts = vc.GetTimestamp("node1");
// Assert
ts.ShouldBe(default(HlcTimestamp));
}
/// <summary>
/// Verifies setting a timestamp stores it for the specified node.
/// </summary>
[Fact]
public void SetTimestamp_ShouldStoreTimestamp()
{
ts.ShouldBe(default);
}
/// <summary>
/// Verifies setting a timestamp stores it for the specified node.
/// </summary>
[Fact]
public void SetTimestamp_ShouldStoreTimestamp()
{
// Arrange
var vc = new VectorClock();
var ts = new HlcTimestamp(100, 1, "node1");
@@ -36,15 +32,15 @@ public class VectorClockTests
vc.SetTimestamp("node1", ts);
// Assert
vc.GetTimestamp("node1").ShouldBe(ts);
}
/// <summary>
/// Verifies node identifiers are returned for all known nodes.
/// </summary>
[Fact]
public void NodeIds_ShouldReturnAllNodes()
{
vc.GetTimestamp("node1").ShouldBe(ts);
}
/// <summary>
/// Verifies node identifiers are returned for all known nodes.
/// </summary>
[Fact]
public void NodeIds_ShouldReturnAllNodes()
{
// Arrange
var vc = new VectorClock();
vc.SetTimestamp("node1", new HlcTimestamp(100, 1, "node1"));
@@ -56,15 +52,15 @@ public class VectorClockTests
// Assert
nodeIds.Count.ShouldBe(2);
nodeIds.ShouldContain("node1");
nodeIds.ShouldContain("node2");
}
/// <summary>
/// Verifies equal vector clocks are compared as equal.
/// </summary>
[Fact]
public void CompareTo_EqualClocks_ShouldReturnEqual()
{
nodeIds.ShouldContain("node2");
}
/// <summary>
/// Verifies equal vector clocks are compared as equal.
/// </summary>
[Fact]
public void CompareTo_EqualClocks_ShouldReturnEqual()
{
// Arrange
var vc1 = new VectorClock();
vc1.SetTimestamp("node1", new HlcTimestamp(100, 1, "node1"));
@@ -78,15 +74,15 @@ public class VectorClockTests
var result = vc1.CompareTo(vc2);
// Assert
result.ShouldBe(CausalityRelation.Equal);
}
/// <summary>
/// Verifies a clock strictly ahead of another is reported as strictly ahead.
/// </summary>
[Fact]
public void CompareTo_StrictlyAhead_ShouldReturnStrictlyAhead()
{
result.ShouldBe(CausalityRelation.Equal);
}
/// <summary>
/// Verifies a clock strictly ahead of another is reported as strictly ahead.
/// </summary>
[Fact]
public void CompareTo_StrictlyAhead_ShouldReturnStrictlyAhead()
{
// Arrange
var vc1 = new VectorClock();
vc1.SetTimestamp("node1", new HlcTimestamp(200, 1, "node1")); // Ahead
@@ -100,15 +96,15 @@ public class VectorClockTests
var result = vc1.CompareTo(vc2);
// Assert
result.ShouldBe(CausalityRelation.StrictlyAhead);
}
/// <summary>
/// Verifies a clock strictly behind another is reported as strictly behind.
/// </summary>
[Fact]
public void CompareTo_StrictlyBehind_ShouldReturnStrictlyBehind()
{
result.ShouldBe(CausalityRelation.StrictlyAhead);
}
/// <summary>
/// Verifies a clock strictly behind another is reported as strictly behind.
/// </summary>
[Fact]
public void CompareTo_StrictlyBehind_ShouldReturnStrictlyBehind()
{
// Arrange
var vc1 = new VectorClock();
vc1.SetTimestamp("node1", new HlcTimestamp(100, 1, "node1")); // Behind
@@ -122,15 +118,15 @@ public class VectorClockTests
var result = vc1.CompareTo(vc2);
// Assert
result.ShouldBe(CausalityRelation.StrictlyBehind);
}
/// <summary>
/// Verifies divergent per-node progress is reported as concurrent.
/// </summary>
[Fact]
public void CompareTo_Concurrent_ShouldReturnConcurrent()
{
result.ShouldBe(CausalityRelation.StrictlyBehind);
}
/// <summary>
/// Verifies divergent per-node progress is reported as concurrent.
/// </summary>
[Fact]
public void CompareTo_Concurrent_ShouldReturnConcurrent()
{
// Arrange - Split brain scenario
var vc1 = new VectorClock();
vc1.SetTimestamp("node1", new HlcTimestamp(200, 1, "node1")); // Node1 ahead
@@ -144,15 +140,15 @@ public class VectorClockTests
var result = vc1.CompareTo(vc2);
// Assert
result.ShouldBe(CausalityRelation.Concurrent);
}
/// <summary>
/// Verifies pull candidates include nodes where the other clock is ahead.
/// </summary>
[Fact]
public void GetNodesWithUpdates_ShouldReturnNodesWhereOtherIsAhead()
{
result.ShouldBe(CausalityRelation.Concurrent);
}
/// <summary>
/// Verifies pull candidates include nodes where the other clock is ahead.
/// </summary>
[Fact]
public void GetNodesWithUpdates_ShouldReturnNodesWhereOtherIsAhead()
{
// Arrange
var vc1 = new VectorClock();
vc1.SetTimestamp("node1", new HlcTimestamp(100, 1, "node1"));
@@ -167,15 +163,15 @@ public class VectorClockTests
// Assert
nodesToPull.Count().ShouldBe(1);
nodesToPull.ShouldContain("node1");
}
/// <summary>
/// Verifies push candidates include nodes where this clock is ahead.
/// </summary>
[Fact]
public void GetNodesToPush_ShouldReturnNodesWhereThisIsAhead()
{
nodesToPull.ShouldContain("node1");
}
/// <summary>
/// Verifies push candidates include nodes where this clock is ahead.
/// </summary>
[Fact]
public void GetNodesToPush_ShouldReturnNodesWhereThisIsAhead()
{
// Arrange
var vc1 = new VectorClock();
vc1.SetTimestamp("node1", new HlcTimestamp(200, 1, "node1")); // Ahead
@@ -190,15 +186,15 @@ public class VectorClockTests
// Assert
nodesToPush.Count().ShouldBe(1);
nodesToPush.ShouldContain("node1");
}
/// <summary>
/// Verifies a newly introduced remote node is included in pull candidates.
/// </summary>
[Fact]
public void GetNodesWithUpdates_WhenNewNodeAppearsInOther_ShouldReturnIt()
{
nodesToPush.ShouldContain("node1");
}
/// <summary>
/// Verifies a newly introduced remote node is included in pull candidates.
/// </summary>
[Fact]
public void GetNodesWithUpdates_WhenNewNodeAppearsInOther_ShouldReturnIt()
{
// Arrange - Simulates a new node joining the cluster
var vc1 = new VectorClock();
vc1.SetTimestamp("node1", new HlcTimestamp(100, 1, "node1"));
@@ -212,15 +208,15 @@ public class VectorClockTests
// Assert
nodesToPull.Count().ShouldBe(1);
nodesToPull.ShouldContain("node3");
}
/// <summary>
/// Verifies merge keeps the maximum timestamp per node.
/// </summary>
[Fact]
public void Merge_ShouldTakeMaximumForEachNode()
{
nodesToPull.ShouldContain("node3");
}
/// <summary>
/// Verifies merge keeps the maximum timestamp per node.
/// </summary>
[Fact]
public void Merge_ShouldTakeMaximumForEachNode()
{
// Arrange
var vc1 = new VectorClock();
vc1.SetTimestamp("node1", new HlcTimestamp(200, 1, "node1"));
@@ -234,18 +230,18 @@ public class VectorClockTests
// Act
vc1.Merge(vc2);
// Assert
vc1.GetTimestamp("node1").ShouldBe(new HlcTimestamp(200, 1, "node1")); // Kept max
vc1.GetTimestamp("node2").ShouldBe(new HlcTimestamp(200, 2, "node2")); // Merged max
vc1.GetTimestamp("node3").ShouldBe(new HlcTimestamp(150, 1, "node3")); // Added new
}
/// <summary>
/// Verifies cloning creates an independent copy of the vector clock.
/// </summary>
[Fact]
public void Clone_ShouldCreateIndependentCopy()
{
// Assert
vc1.GetTimestamp("node1").ShouldBe(new HlcTimestamp(200, 1, "node1")); // Kept max
vc1.GetTimestamp("node2").ShouldBe(new HlcTimestamp(200, 2, "node2")); // Merged max
vc1.GetTimestamp("node3").ShouldBe(new HlcTimestamp(150, 1, "node3")); // Added new
}
/// <summary>
/// Verifies cloning creates an independent copy of the vector clock.
/// </summary>
[Fact]
public void Clone_ShouldCreateIndependentCopy()
{
// Arrange
var vc1 = new VectorClock();
vc1.SetTimestamp("node1", new HlcTimestamp(100, 1, "node1"));
@@ -256,15 +252,15 @@ public class VectorClockTests
// Assert
vc1.NodeIds.Count().ShouldBe(1);
vc2.NodeIds.Count().ShouldBe(2);
}
/// <summary>
/// Verifies the string representation includes serialized node timestamps.
/// </summary>
[Fact]
public void ToString_ShouldReturnReadableFormat()
{
vc2.NodeIds.Count().ShouldBe(2);
}
/// <summary>
/// Verifies the string representation includes serialized node timestamps.
/// </summary>
[Fact]
public void ToString_ShouldReturnReadableFormat()
{
// Arrange
var vc = new VectorClock();
vc.SetTimestamp("node1", new HlcTimestamp(100, 1, "node1"));
@@ -275,15 +271,15 @@ public class VectorClockTests
// Assert
str.ShouldContain("node1:100:1:node1");
str.ShouldContain("node2:200:2:node2");
}
/// <summary>
/// Verifies split-brain updates are detected as concurrent.
/// </summary>
[Fact]
public void SplitBrainScenario_ShouldDetectConcurrency()
{
str.ShouldContain("node2:200:2:node2");
}
/// <summary>
/// Verifies split-brain updates are detected as concurrent.
/// </summary>
[Fact]
public void SplitBrainScenario_ShouldDetectConcurrency()
{
// Arrange - Simulating a network partition scenario
// Partition 1: node1 and node2 are alive
var vcPartition1 = new VectorClock();
@@ -310,4 +306,4 @@ public class VectorClockTests
partition1NeedsToPush.ShouldContain("node1");
partition1NeedsToPush.ShouldContain("node2");
}
}
}