github.com/matrixorigin/matrixone@v1.2.0/pkg/txn/clock/hlc_test.go (about) 1 // Copyright 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package clock 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/pb/timestamp" 23 "github.com/stretchr/testify/assert" 24 ) 25 26 type Timestamp = timestamp.Timestamp 27 28 func TestToMicrosecond(t *testing.T) { 29 assert.Equal(t, int64(1), toMicrosecond(1000)) 30 } 31 32 func TestPhysicalClockReturnsNanoseconds(t *testing.T) { 33 v1 := physicalClock() 34 time.Sleep(1 * time.Microsecond) 35 v2 := physicalClock() 36 assert.True(t, v2-v1 >= 1e3) 37 } 38 39 func TestSkipClockUncertainityPeriodOnRestart(t *testing.T) { 40 ctx, cancel := context.WithCancel(context.Background()) 41 defer cancel() 42 // maxOffset below has to be set to a relatively large value, we repeatedly 43 // saw cpu starvations of several milliseconds in tests running on github 44 // actions. 45 c := NewUnixNanoHLCClock(ctx, 500*time.Millisecond) 46 v1 := physicalClock() 47 SkipClockUncertainityPeriodOnRestart(ctx, c) 48 v2 := physicalClock() 49 assert.True(t, v2-v1 >= 500*1e6) 50 } 51 52 func TestNewHLCClock(t *testing.T) { 53 c := NewHLCClock(physicalClock, time.Second) 54 assert.Equal(t, time.Second, c.maxOffset) 55 } 56 57 func TestNewUnixNanoHLCClock(t *testing.T) { 58 v := physicalClock() 59 ctx, cancel := context.WithCancel(context.Background()) 60 defer cancel() 61 c := NewUnixNanoHLCClock(ctx, 500*time.Millisecond) 62 result, _ := c.Now() 63 assert.True(t, v < result.PhysicalTime) 64 } 65 66 func TestMaxClockForwardOffset(t *testing.T) { 67 c := NewHLCClock(physicalClock, 2*time.Second) 68 assert.Equal(t, time.Second, c.maxClockForwardOffset()) 69 } 70 71 func TestKeepPhysicalClock(t *testing.T) { 72 c := NewHLCClock(physicalClock, time.Second) 73 c.mu.maxLearnedPhysicalTime = 1234 74 result := c.keepPhysicalClock(1233) 75 assert.Equal(t, int64(1234), result) 76 assert.Equal(t, int64(1234), c.mu.maxLearnedPhysicalTime) 77 78 result = c.keepPhysicalClock(1235) 79 assert.Equal(t, int64(1234), result) 80 assert.Equal(t, int64(1235), c.mu.maxLearnedPhysicalTime) 81 } 82 83 func TestGetPhysicalClock(t *testing.T) { 84 pc := func() int64 { 85 return 200 86 } 87 c := NewHLCClock(pc, time.Second) 88 c.mu.maxLearnedPhysicalTime = 123 89 result := c.getPhysicalClock() 90 assert.Equal(t, int64(200), result) 91 assert.Equal(t, int64(200), c.mu.maxLearnedPhysicalTime) 92 93 c.mu.maxLearnedPhysicalTime = 300 94 result = c.getPhysicalClock() 95 assert.Equal(t, int64(200), result) 96 assert.Equal(t, int64(300), c.mu.maxLearnedPhysicalTime) 97 } 98 99 func TestNow(t *testing.T) { 100 pc := func() int64 { 101 return 200 102 } 103 c := NewHLCClock(pc, time.Second) 104 105 c.mu.ts = Timestamp{PhysicalTime: 100, LogicalTime: 10} 106 result, _ := c.Now() 107 assert.Equal(t, Timestamp{PhysicalTime: 200}, result) 108 109 c.mu.ts = Timestamp{PhysicalTime: 300, LogicalTime: 10} 110 result, _ = c.Now() 111 assert.Equal(t, Timestamp{PhysicalTime: 300, LogicalTime: 11}, result) 112 113 result, upperBound := c.Now() 114 assert.Equal(t, result.PhysicalTime+int64(c.MaxOffset()), upperBound.PhysicalTime) 115 assert.Equal(t, uint32(0), upperBound.LogicalTime) 116 } 117 118 func TestUpdate(t *testing.T) { 119 pc := func() int64 { 120 return 200 121 } 122 c := NewHLCClock(pc, time.Second) 123 124 // pt is the max 125 c.mu.ts = Timestamp{PhysicalTime: 100, LogicalTime: 10} 126 c.Update(Timestamp{PhysicalTime: 120}) 127 assert.Equal(t, Timestamp{PhysicalTime: 200}, c.mu.ts) 128 129 c.physicalClock = func() int64 { return 50 } 130 // m has the same physical time and greater logical time 131 c.mu.ts = Timestamp{PhysicalTime: 100, LogicalTime: 10} 132 c.Update(Timestamp{PhysicalTime: 100, LogicalTime: 100}) 133 assert.Equal(t, Timestamp{PhysicalTime: 100, LogicalTime: 100}, c.mu.ts) 134 135 // m has the largest physical time 136 c.mu.ts = Timestamp{PhysicalTime: 100, LogicalTime: 10} 137 m := Timestamp{PhysicalTime: 120, LogicalTime: 100} 138 c.Update(m) 139 assert.Equal(t, m, c.mu.ts) 140 141 // m has smaller physical time 142 c.mu.ts = Timestamp{PhysicalTime: 100, LogicalTime: 10} 143 old := c.mu.ts 144 c.Update(Timestamp{PhysicalTime: 99, LogicalTime: 100}) 145 assert.Equal(t, old, c.mu.ts) 146 }