155 lines
3.7 KiB
Go
155 lines
3.7 KiB
Go
package clock
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestLamportClock_Tick(t *testing.T) {
|
|
nodeID := NodeID{1, 2, 3}
|
|
clock := NewLamportClock(nodeID)
|
|
|
|
// Initial tick should return 1
|
|
ts1 := clock.Tick()
|
|
if ts1.Counter != 1 {
|
|
t.Errorf("Expected counter to be 1, got %d", ts1.Counter)
|
|
}
|
|
|
|
// Next tick should return 2
|
|
ts2 := clock.Tick()
|
|
if ts2.Counter != 2 {
|
|
t.Errorf("Expected counter to be 2, got %d", ts2.Counter)
|
|
}
|
|
|
|
// NodeID should be preserved
|
|
if !ts1.Node.Equal(nodeID) {
|
|
t.Errorf("NodeID not preserved in timestamp")
|
|
}
|
|
}
|
|
|
|
func TestLamportClock_Update(t *testing.T) {
|
|
nodeID1 := NodeID{1, 2, 3}
|
|
nodeID2 := NodeID{4, 5, 6}
|
|
|
|
clock1 := NewLamportClock(nodeID1)
|
|
clock2 := NewLamportClock(nodeID2)
|
|
|
|
// Advance clock1 to 5
|
|
for i := 0; i < 5; i++ {
|
|
clock1.Tick()
|
|
}
|
|
|
|
// Get current timestamp from clock1
|
|
ts1 := clock1.GetCurrent()
|
|
if ts1.Counter != 5 {
|
|
t.Errorf("Expected counter to be 5, got %d", ts1.Counter)
|
|
}
|
|
|
|
// Update clock2 with timestamp from clock1
|
|
ts2 := clock2.Update(ts1)
|
|
|
|
// Clock2 should now be at least as large as clock1's timestamp + 1
|
|
if ts2.Counter <= ts1.Counter {
|
|
t.Errorf("Expected clock2 counter > %d, got %d", ts1.Counter, ts2.Counter)
|
|
}
|
|
|
|
// Clock2's NodeID should still be nodeID2
|
|
if !ts2.Node.Equal(nodeID2) {
|
|
t.Errorf("NodeID not preserved after update")
|
|
}
|
|
}
|
|
|
|
func TestLamportClock_Ordering(t *testing.T) {
|
|
nodeID1 := NodeID{1, 2, 3}
|
|
nodeID2 := NodeID{4, 5, 6}
|
|
|
|
// Create timestamps with the same counter but different NodeIDs
|
|
ts1 := Timestamp{Counter: 5, Node: nodeID1}
|
|
ts2 := Timestamp{Counter: 5, Node: nodeID2}
|
|
|
|
// Compare should break ties using NodeID
|
|
if Compare(ts1, ts2) >= 0 {
|
|
t.Errorf("Expected ts1 < ts2 when counters are equal")
|
|
}
|
|
|
|
// Create timestamps with different counters
|
|
ts3 := Timestamp{Counter: 6, Node: nodeID1}
|
|
ts4 := Timestamp{Counter: 5, Node: nodeID2}
|
|
|
|
// Compare should prioritize counter values
|
|
if Compare(ts3, ts4) <= 0 {
|
|
t.Errorf("Expected ts3 > ts4 when ts3.Counter > ts4.Counter")
|
|
}
|
|
}
|
|
|
|
func TestLamportClock_Serialization(t *testing.T) {
|
|
nodeID := NodeID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
|
|
ts := Timestamp{Counter: 42, Node: nodeID}
|
|
|
|
// Serialize
|
|
bytes := ts.Bytes()
|
|
|
|
// Deserialize
|
|
ts2, err := TimestampFromBytes(bytes)
|
|
if err != nil {
|
|
t.Fatalf("Failed to deserialize timestamp: %v", err)
|
|
}
|
|
|
|
// Compare
|
|
if ts.Counter != ts2.Counter {
|
|
t.Errorf("Counter not preserved in serialization, expected %d got %d", ts.Counter, ts2.Counter)
|
|
}
|
|
|
|
if !ts.Node.Equal(ts2.Node) {
|
|
t.Errorf("NodeID not preserved in serialization")
|
|
}
|
|
}
|
|
|
|
func TestLamportClock_Concurrent(t *testing.T) {
|
|
nodeID := NodeID{1, 2, 3}
|
|
clock := NewLamportClock(nodeID)
|
|
|
|
// Run 100 concurrent ticks
|
|
done := make(chan struct{})
|
|
for i := 0; i < 100; i++ {
|
|
go func() {
|
|
clock.Tick()
|
|
done <- struct{}{}
|
|
}()
|
|
}
|
|
|
|
// Wait for all ticks to complete
|
|
for i := 0; i < 100; i++ {
|
|
<-done
|
|
}
|
|
|
|
// Counter should be 100
|
|
ts := clock.GetCurrent()
|
|
if ts.Counter != 100 {
|
|
t.Errorf("Expected counter to be 100 after 100 concurrent ticks, got %d", ts.Counter)
|
|
}
|
|
}
|
|
|
|
func TestLamportClock_ManualSet(t *testing.T) {
|
|
nodeID := NodeID{1, 2, 3}
|
|
clock := NewLamportClock(nodeID)
|
|
|
|
// Set to a high value
|
|
clock.ManualSet(1000)
|
|
ts := clock.GetCurrent()
|
|
if ts.Counter != 1000 {
|
|
t.Errorf("Expected counter to be 1000 after ManualSet, got %d", ts.Counter)
|
|
}
|
|
|
|
// Setting to a lower value should have no effect
|
|
clock.ManualSet(500)
|
|
ts = clock.GetCurrent()
|
|
if ts.Counter != 1000 {
|
|
t.Errorf("Expected counter to remain 1000 after lower ManualSet, got %d", ts.Counter)
|
|
}
|
|
|
|
// Tick should still increment
|
|
ts = clock.Tick()
|
|
if ts.Counter != 1001 {
|
|
t.Errorf("Expected counter to be 1001 after tick, got %d", ts.Counter)
|
|
}
|
|
} |