github.com/amazechain/amc@v0.1.3/internal/tracers/tracker_test.go (about) 1 // Copyright 2022 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/> 16 17 package tracers 18 19 import ( 20 "reflect" 21 "testing" 22 "time" 23 ) 24 25 func TestTracker(t *testing.T) { 26 var cases = []struct { 27 limit int 28 calls []uint64 29 expHead uint64 30 }{ 31 // Release in order 32 { 33 limit: 3, 34 calls: []uint64{0, 1, 2}, 35 expHead: 3, 36 }, 37 { 38 limit: 3, 39 calls: []uint64{0, 1, 2, 3, 4, 5}, 40 expHead: 6, 41 }, 42 43 // Release out of order 44 { 45 limit: 3, 46 calls: []uint64{1, 2, 0}, 47 expHead: 3, 48 }, 49 { 50 limit: 3, 51 calls: []uint64{1, 2, 0, 5, 4, 3}, 52 expHead: 6, 53 }, 54 } 55 for _, c := range cases { 56 tracker := newStateTracker(c.limit, 0) 57 for _, call := range c.calls { 58 tracker.releaseState(call, func() {}) 59 } 60 tracker.lock.RLock() 61 head := tracker.oldest 62 tracker.lock.RUnlock() 63 64 if head != c.expHead { 65 t.Fatalf("Unexpected head want %d got %d", c.expHead, head) 66 } 67 } 68 69 var calls = []struct { 70 number uint64 71 expUsed []bool 72 expHead uint64 73 }{ 74 // Release the first one, update the oldest flag 75 { 76 number: 0, 77 expUsed: []bool{false, false, false, false, false}, 78 expHead: 1, 79 }, 80 // Release the second one, oldest shouldn't be updated 81 { 82 number: 2, 83 expUsed: []bool{false, true, false, false, false}, 84 expHead: 1, 85 }, 86 // Release the forth one, oldest shouldn't be updated 87 { 88 number: 4, 89 expUsed: []bool{false, true, false, true, false}, 90 expHead: 1, 91 }, 92 // Release the first one, the first two should all be cleaned, 93 // and the remaining flags should all be left-shifted. 94 { 95 number: 1, 96 expUsed: []bool{false, true, false, false, false}, 97 expHead: 3, 98 }, 99 // Release the first one, the first two should all be cleaned 100 { 101 number: 3, 102 expUsed: []bool{false, false, false, false, false}, 103 expHead: 5, 104 }, 105 } 106 tracker := newStateTracker(5, 0) // limit = 5, oldest = 0 107 for _, call := range calls { 108 tracker.releaseState(call.number, nil) 109 tracker.lock.RLock() 110 if !reflect.DeepEqual(tracker.used, call.expUsed) { 111 t.Fatalf("Unexpected used array") 112 } 113 if tracker.oldest != call.expHead { 114 t.Fatalf("Unexpected head") 115 } 116 tracker.lock.RUnlock() 117 } 118 } 119 120 func TestTrackerWait(t *testing.T) { 121 var ( 122 tracker = newStateTracker(5, 0) // limit = 5, oldest = 0 123 result = make(chan error, 1) 124 doCall = func(number uint64) { 125 go func() { 126 result <- tracker.wait(number) 127 }() 128 } 129 checkNoWait = func() { 130 select { 131 case <-result: 132 return 133 case <-time.NewTimer(time.Second).C: 134 t.Fatal("No signal fired") 135 } 136 } 137 checkWait = func() { 138 select { 139 case <-result: 140 t.Fatal("Unexpected signal") 141 case <-time.NewTimer(time.Millisecond * 100).C: 142 } 143 } 144 ) 145 // States [0, 5) should all be available 146 doCall(0) 147 checkNoWait() 148 149 doCall(4) 150 checkNoWait() 151 152 // State 5 is not available 153 doCall(5) 154 checkWait() 155 156 // States [1, 6) are available 157 tracker.releaseState(0, nil) 158 checkNoWait() 159 160 // States [1, 6) are available 161 doCall(7) 162 checkWait() 163 164 // States [2, 7) are available 165 tracker.releaseState(1, nil) 166 checkWait() 167 168 // States [3, 8) are available 169 tracker.releaseState(2, nil) 170 checkNoWait() 171 }