github.com/database64128/shadowsocks-go@v1.10.2-0.20240315062903-143a773533f1/ss2022/slidingwindow_test.go (about) 1 package ss2022 2 3 import ( 4 "strconv" 5 "testing" 6 ) 7 8 func testIsOkMustAdd(t *testing.T, f *SlidingWindowFilter) { 9 f.Reset() 10 i := uint64(1) 11 n := uint64(len(f.ring)+1) * swfBlockBits 12 13 // Add 1, 3, 5, ..., n-1. 14 for ; i < n; i += 2 { 15 if !f.IsOk(i) { 16 t.Error(i, "should be ok.") 17 } 18 f.MustAdd(i) 19 } 20 21 // Check 0, 2, 4, ..., 126. 22 for i = 0; i < n-f.size; i += 2 { 23 if f.IsOk(i) { 24 t.Error(i, "should not be ok.") 25 } 26 } 27 28 // Check 128, 130, 132, ..., n-2. 29 for ; i < n; i += 2 { 30 if !f.IsOk(i) { 31 t.Error(i, "should be ok.") 32 } 33 } 34 35 // Check 1, 3, 5, ..., n-1. 36 for i = 1; i < n; i += 2 { 37 if f.IsOk(i) { 38 t.Error(i, "should not be ok.") 39 } 40 } 41 42 // Roll over the window. 43 n <<= 1 44 if !f.IsOk(n) { 45 t.Error(n, "should be ok.") 46 } 47 f.MustAdd(n) 48 49 // Check behind window. 50 for i = 0; i < n-f.size+1; i++ { 51 if f.IsOk(i) { 52 t.Error(i, "should not be ok.") 53 } 54 } 55 56 // Check within window. 57 for ; i < n; i++ { 58 if !f.IsOk(i) { 59 t.Error(i, "should be ok.") 60 } 61 } 62 63 // Check n. 64 if i == n { 65 if f.IsOk(i) { 66 t.Error(i, "should not be ok.") 67 } 68 i++ 69 } 70 71 // Check after window. 72 for ; i < n+f.size; i++ { 73 if !f.IsOk(i) { 74 t.Error(i, "should be ok.") 75 } 76 } 77 } 78 79 func testAdd(t *testing.T, f *SlidingWindowFilter) { 80 f.Reset() 81 i := uint64(1) 82 n := uint64(len(f.ring)+1) * swfBlockBits 83 84 // Add 1, 3, 5, ..., n-1. 85 for ; i < n; i += 2 { 86 if !f.Add(i) { 87 t.Error(i, "should succeed.") 88 } 89 } 90 91 // Check 0, 2, 4, ..., 126. 92 for i = 0; i < n-f.size; i += 2 { 93 if f.Add(i) { 94 t.Error(i, "should fail.") 95 } 96 } 97 98 // Check 128, 130, 132, ..., n-2. 99 for ; i < n; i += 2 { 100 if !f.Add(i) { 101 t.Error(i, "should succeed.") 102 } 103 } 104 105 // Check 1, 3, 5, ..., n-1. 106 for i = 1; i < n; i += 2 { 107 if f.Add(i) { 108 t.Error(i, "should fail.") 109 } 110 } 111 112 // Roll over the window. 113 n <<= 1 114 if !f.Add(n) { 115 t.Error(n, "should succeed.") 116 } 117 118 // Check behind window. 119 for i = 0; i < n-f.size+1; i++ { 120 if f.Add(i) { 121 t.Error(i, "should fail.") 122 } 123 } 124 125 // Check within window. 126 for ; i < n; i++ { 127 if !f.Add(i) { 128 t.Error(i, "should succeed.") 129 } 130 } 131 132 // Check n. 133 if i == n { 134 if f.Add(i) { 135 t.Error(i, "should fail.") 136 } 137 i++ 138 } 139 140 // Check after window. 141 for ; i < n+f.size; i++ { 142 if !f.Add(i) { 143 t.Error(i, "should succeed.") 144 } 145 } 146 } 147 148 func testReset(t *testing.T, f *SlidingWindowFilter) { 149 n := f.Size() * 2 150 151 for i := uint64(0); i < n; i++ { 152 f.MustAdd(i) 153 } 154 155 f.Reset() 156 157 for i := uint64(0); i < n; i++ { 158 if !f.IsOk(i) { 159 t.Error(i, "should be ok.") 160 } 161 } 162 } 163 164 func testSlidingWindowFilter(t *testing.T, f *SlidingWindowFilter) { 165 t.Run("IsOkMustAdd", func(t *testing.T) { 166 testIsOkMustAdd(t, f) 167 }) 168 t.Run("Add", func(t *testing.T) { 169 testAdd(t, f) 170 }) 171 t.Run("Reset", func(t *testing.T) { 172 testReset(t, f) 173 }) 174 } 175 176 func TestSlidingWindowFilter(t *testing.T) { 177 sizes := []uint64{0, 1, 2, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, 256, 257} 178 for _, size := range sizes { 179 t.Run(strconv.FormatUint(size, 10), func(t *testing.T) { 180 f := NewSlidingWindowFilter(size) 181 t.Log("ringBlockIndexMask", f.ringBlockIndexMask) 182 testSlidingWindowFilter(t, f) 183 }) 184 } 185 }