github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/bitmap/sequence_test.go (about) 1 package bitmap 2 3 import ( 4 "math/rand" 5 "testing" 6 "time" 7 ) 8 9 func TestSequenceGetAvailableBit(t *testing.T) { 10 input := []struct { 11 head *sequence 12 from uint64 13 bytePos uint64 14 bitPos uint64 15 }{ 16 {&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos}, 17 {&sequence{block: 0x0, count: 1}, 0, 0, 0}, 18 {&sequence{block: 0x0, count: 100}, 0, 0, 0}, 19 20 {&sequence{block: 0x80000000, count: 0}, 0, invalidPos, invalidPos}, 21 {&sequence{block: 0x80000000, count: 1}, 0, 0, 1}, 22 {&sequence{block: 0x80000000, count: 100}, 0, 0, 1}, 23 24 {&sequence{block: 0xFF000000, count: 0}, 0, invalidPos, invalidPos}, 25 {&sequence{block: 0xFF000000, count: 1}, 0, 1, 0}, 26 {&sequence{block: 0xFF000000, count: 100}, 0, 1, 0}, 27 28 {&sequence{block: 0xFF800000, count: 0}, 0, invalidPos, invalidPos}, 29 {&sequence{block: 0xFF800000, count: 1}, 0, 1, 1}, 30 {&sequence{block: 0xFF800000, count: 100}, 0, 1, 1}, 31 32 {&sequence{block: 0xFFC0FF00, count: 0}, 0, invalidPos, invalidPos}, 33 {&sequence{block: 0xFFC0FF00, count: 1}, 0, 1, 2}, 34 {&sequence{block: 0xFFC0FF00, count: 100}, 0, 1, 2}, 35 36 {&sequence{block: 0xFFE0FF00, count: 0}, 0, invalidPos, invalidPos}, 37 {&sequence{block: 0xFFE0FF00, count: 1}, 0, 1, 3}, 38 {&sequence{block: 0xFFE0FF00, count: 100}, 0, 1, 3}, 39 40 {&sequence{block: 0xFFFEFF00, count: 0}, 0, invalidPos, invalidPos}, 41 {&sequence{block: 0xFFFEFF00, count: 1}, 0, 1, 7}, 42 {&sequence{block: 0xFFFEFF00, count: 100}, 0, 1, 7}, 43 44 {&sequence{block: 0xFFFFC0FF, count: 0}, 0, invalidPos, invalidPos}, 45 {&sequence{block: 0xFFFFC0FF, count: 1}, 0, 2, 2}, 46 {&sequence{block: 0xFFFFC0FF, count: 100}, 0, 2, 2}, 47 48 {&sequence{block: 0xFFFFFF00, count: 0}, 0, invalidPos, invalidPos}, 49 {&sequence{block: 0xFFFFFF00, count: 1}, 0, 3, 0}, 50 {&sequence{block: 0xFFFFFF00, count: 100}, 0, 3, 0}, 51 52 {&sequence{block: 0xFFFFFFFE, count: 0}, 0, invalidPos, invalidPos}, 53 {&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7}, 54 {&sequence{block: 0xFFFFFFFE, count: 100}, 0, 3, 7}, 55 56 {&sequence{block: 0xFFFFFFFF, count: 0}, 0, invalidPos, invalidPos}, 57 {&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos}, 58 {&sequence{block: 0xFFFFFFFF, count: 100}, 0, invalidPos, invalidPos}, 59 60 // now test with offset 61 {&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos}, 62 {&sequence{block: 0x0, count: 0}, 31, invalidPos, invalidPos}, 63 {&sequence{block: 0x0, count: 0}, 32, invalidPos, invalidPos}, 64 {&sequence{block: 0x0, count: 1}, 0, 0, 0}, 65 {&sequence{block: 0x0, count: 1}, 1, 0, 1}, 66 {&sequence{block: 0x0, count: 1}, 31, 3, 7}, 67 {&sequence{block: 0xF0FF0000, count: 1}, 0, 0, 4}, 68 {&sequence{block: 0xF0FF0000, count: 1}, 8, 2, 0}, 69 {&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos}, 70 {&sequence{block: 0xFFFFFFFF, count: 1}, 16, invalidPos, invalidPos}, 71 {&sequence{block: 0xFFFFFFFF, count: 1}, 31, invalidPos, invalidPos}, 72 {&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7}, 73 {&sequence{block: 0xFFFFFFFF, count: 2}, 0, invalidPos, invalidPos}, 74 {&sequence{block: 0xFFFFFFFF, count: 2}, 32, invalidPos, invalidPos}, 75 } 76 77 for n, i := range input { 78 b, bb, err := i.head.getAvailableBit(i.from) 79 if b != i.bytePos || bb != i.bitPos { 80 t.Fatalf("Error in sequence.getAvailableBit(%d) (%d).\nExp: (%d, %d)\nGot: (%d, %d), err: %v", i.from, n, i.bytePos, i.bitPos, b, bb, err) 81 } 82 } 83 } 84 85 func TestSequenceEqual(t *testing.T) { 86 input := []struct { 87 first *sequence 88 second *sequence 89 areEqual bool 90 }{ 91 {&sequence{block: 0x0, count: 8, next: nil}, &sequence{block: 0x0, count: 8}, true}, 92 {&sequence{block: 0x0, count: 0, next: nil}, &sequence{block: 0x0, count: 0}, true}, 93 {&sequence{block: 0x0, count: 2, next: nil}, &sequence{block: 0x0, count: 1, next: &sequence{block: 0x0, count: 1}}, false}, 94 {&sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}, &sequence{block: 0x0, count: 2}, false}, 95 96 {&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 8}, true}, 97 {&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 9}, false}, 98 {&sequence{block: 0x12345678, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 1}}, &sequence{block: 0x12345678, count: 1}, false}, 99 {&sequence{block: 0x12345678, count: 1}, &sequence{block: 0x12345678, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 1}}, false}, 100 } 101 102 for n, i := range input { 103 if i.areEqual != i.first.equal(i.second) { 104 t.Fatalf("Error in sequence.equal() (%d).\nExp: %t\nGot: %t,", n, i.areEqual, !i.areEqual) 105 } 106 } 107 } 108 109 func TestSequenceCopy(t *testing.T) { 110 s := getTestSequence() 111 n := s.getCopy() 112 if !s.equal(n) { 113 t.Fatal("copy of s failed") 114 } 115 if n == s { 116 t.Fatal("not true copy of s") 117 } 118 } 119 120 func TestGetFirstAvailable(t *testing.T) { 121 input := []struct { 122 mask *sequence 123 bytePos uint64 124 bitPos uint64 125 start uint64 126 }{ 127 {&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos, 0}, 128 {&sequence{block: 0x0, count: 8}, 0, 0, 0}, 129 {&sequence{block: 0x80000000, count: 8}, 0, 1, 0}, 130 {&sequence{block: 0xC0000000, count: 8}, 0, 2, 0}, 131 {&sequence{block: 0xE0000000, count: 8}, 0, 3, 0}, 132 {&sequence{block: 0xF0000000, count: 8}, 0, 4, 0}, 133 {&sequence{block: 0xF8000000, count: 8}, 0, 5, 0}, 134 {&sequence{block: 0xFC000000, count: 8}, 0, 6, 0}, 135 {&sequence{block: 0xFE000000, count: 8}, 0, 7, 0}, 136 {&sequence{block: 0xFE000000, count: 8}, 3, 0, 24}, 137 138 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 0, 0}, 139 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1, 0}, 140 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2, 0}, 141 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3, 0}, 142 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4, 0}, 143 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5, 0}, 144 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6, 0}, 145 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7, 0}, 146 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x0E000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 0, 16}, 147 148 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0, 0}, 149 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1, 0}, 150 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2, 0}, 151 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3, 0}, 152 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4, 0}, 153 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5, 0}, 154 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6, 0}, 155 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7, 0}, 156 157 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 7, 7, 0}, 158 159 {&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0, 0}, 160 {&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 4, 0, 16}, 161 {&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 7, 15}, 162 {&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 6, 10}, 163 {&sequence{block: 0xfffcfffe, count: 1, next: &sequence{block: 0x0, count: 6}}, 3, 7, 31}, 164 {&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0xffffffff, count: 6}}, invalidPos, invalidPos, 31}, 165 } 166 167 for n, i := range input { 168 bytePos, bitPos, _ := getFirstAvailable(i.mask, i.start) 169 if bytePos != i.bytePos || bitPos != i.bitPos { 170 t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos) 171 } 172 } 173 } 174 175 func TestFindSequence(t *testing.T) { 176 input := []struct { 177 head *sequence 178 bytePos uint64 179 precBlocks uint64 180 inBlockBytePos uint64 181 }{ 182 {&sequence{block: 0xffffffff, count: 0}, 0, 0, invalidPos}, 183 {&sequence{block: 0xffffffff, count: 0}, 31, 0, invalidPos}, 184 {&sequence{block: 0xffffffff, count: 0}, 100, 0, invalidPos}, 185 186 {&sequence{block: 0x0, count: 1}, 0, 0, 0}, 187 {&sequence{block: 0x0, count: 1}, 1, 0, 1}, 188 {&sequence{block: 0x0, count: 1}, 31, 0, invalidPos}, 189 {&sequence{block: 0x0, count: 1}, 60, 0, invalidPos}, 190 191 {&sequence{block: 0xffffffff, count: 10}, 0, 0, 0}, 192 {&sequence{block: 0xffffffff, count: 10}, 3, 0, 3}, 193 {&sequence{block: 0xffffffff, count: 10}, 4, 1, 0}, 194 {&sequence{block: 0xffffffff, count: 10}, 7, 1, 3}, 195 {&sequence{block: 0xffffffff, count: 10}, 8, 2, 0}, 196 {&sequence{block: 0xffffffff, count: 10}, 39, 9, 3}, 197 198 {&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 79, 9, 3}, 199 {&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 80, 0, invalidPos}, 200 } 201 202 for n, i := range input { 203 _, _, precBlocks, inBlockBytePos := findSequence(i.head, i.bytePos) 204 if precBlocks != i.precBlocks || inBlockBytePos != i.inBlockBytePos { 205 t.Fatalf("Error in (%d) findSequence(). Expected (%d, %d). Got (%d, %d)", n, i.precBlocks, i.inBlockBytePos, precBlocks, inBlockBytePos) 206 } 207 } 208 } 209 210 func TestCheckIfAvailable(t *testing.T) { 211 input := []struct { 212 head *sequence 213 ordinal uint64 214 bytePos uint64 215 bitPos uint64 216 }{ 217 {&sequence{block: 0xffffffff, count: 0}, 0, invalidPos, invalidPos}, 218 {&sequence{block: 0xffffffff, count: 0}, 31, invalidPos, invalidPos}, 219 {&sequence{block: 0xffffffff, count: 0}, 100, invalidPos, invalidPos}, 220 221 {&sequence{block: 0x0, count: 1}, 0, 0, 0}, 222 {&sequence{block: 0x0, count: 1}, 1, 0, 1}, 223 {&sequence{block: 0x0, count: 1}, 31, 3, 7}, 224 {&sequence{block: 0x0, count: 1}, 60, invalidPos, invalidPos}, 225 226 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 31, invalidPos, invalidPos}, 227 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 32, invalidPos, invalidPos}, 228 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 33, 4, 1}, 229 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 33, invalidPos, invalidPos}, 230 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 34, 4, 2}, 231 232 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 55, 6, 7}, 233 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 56, invalidPos, invalidPos}, 234 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 63, invalidPos, invalidPos}, 235 236 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 64, 8, 0}, 237 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 95, 11, 7}, 238 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 96, invalidPos, invalidPos}, 239 } 240 241 for n, i := range input { 242 bytePos, bitPos, err := checkIfAvailable(i.head, i.ordinal) 243 if bytePos != i.bytePos || bitPos != i.bitPos { 244 t.Fatalf("Error in (%d) checkIfAvailable(ord:%d). Expected (%d, %d). Got (%d, %d). err: %v", n, i.ordinal, i.bytePos, i.bitPos, bytePos, bitPos, err) 245 } 246 } 247 } 248 249 func TestMergeSequences(t *testing.T) { 250 input := []struct { 251 original *sequence 252 merged *sequence 253 }{ 254 {&sequence{block: 0xFE000000, count: 8, next: &sequence{block: 0xFE000000, count: 2}}, &sequence{block: 0xFE000000, count: 10}}, 255 {&sequence{block: 0xFFFFFFFF, count: 8, next: &sequence{block: 0xFFFFFFFF, count: 1}}, &sequence{block: 0xFFFFFFFF, count: 9}}, 256 {&sequence{block: 0xFFFFFFFF, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 8}}, &sequence{block: 0xFFFFFFFF, count: 9}}, 257 258 {&sequence{block: 0xFFFFFFF0, count: 8, next: &sequence{block: 0xFFFFFFF0, count: 1}}, &sequence{block: 0xFFFFFFF0, count: 9}}, 259 {&sequence{block: 0xFFFFFFF0, count: 1, next: &sequence{block: 0xFFFFFFF0, count: 8}}, &sequence{block: 0xFFFFFFF0, count: 9}}, 260 261 {&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5}}}, &sequence{block: 0xFE, count: 14}}, 262 { 263 &sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5, next: &sequence{block: 0xFF, count: 1}}}}, 264 &sequence{block: 0xFE, count: 14, next: &sequence{block: 0xFF, count: 1}}, 265 }, 266 267 // No merge 268 { 269 &sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}}, 270 &sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}}, 271 }, 272 273 // No merge from head: // Merge function tries to merge from passed head. If it can't merge with next, it does not reattempt with next as head 274 { 275 &sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 1, next: &sequence{block: 0xFF, count: 5}}}, 276 &sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 6}}, 277 }, 278 } 279 280 for n, i := range input { 281 mergeSequences(i.original) 282 for !i.merged.equal(i.original) { 283 t.Fatalf("Error in (%d) mergeSequences().\nExp: %s\nGot: %s,", n, i.merged.toString(), i.original.toString()) 284 } 285 } 286 } 287 288 func TestPushReservation(t *testing.T) { 289 input := []struct { 290 mask *sequence 291 bytePos uint64 292 bitPos uint64 293 newMask *sequence 294 }{ 295 // Create first sequence and fill in 8 addresses starting from address 0 296 {&sequence{block: 0x0, count: 8, next: nil}, 0, 0, &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}}, 297 {&sequence{block: 0x80000000, count: 8}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x80000000, count: 7, next: nil}}}, 298 {&sequence{block: 0xC0000000, count: 8}, 0, 2, &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xC0000000, count: 7, next: nil}}}, 299 {&sequence{block: 0xE0000000, count: 8}, 0, 3, &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xE0000000, count: 7, next: nil}}}, 300 {&sequence{block: 0xF0000000, count: 8}, 0, 4, &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xF0000000, count: 7, next: nil}}}, 301 {&sequence{block: 0xF8000000, count: 8}, 0, 5, &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xF8000000, count: 7, next: nil}}}, 302 {&sequence{block: 0xFC000000, count: 8}, 0, 6, &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xFC000000, count: 7, next: nil}}}, 303 {&sequence{block: 0xFE000000, count: 8}, 0, 7, &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xFE000000, count: 7, next: nil}}}, 304 305 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7}}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}}, 306 307 // Create second sequence and fill in 8 addresses starting from address 32 308 { 309 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6, next: nil}}}, 4, 0, 310 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 311 }, 312 { 313 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1, 314 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 315 }, 316 { 317 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2, 318 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 319 }, 320 { 321 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3, 322 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 323 }, 324 { 325 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4, 326 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 327 }, 328 { 329 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5, 330 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 331 }, 332 { 333 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6, 334 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 335 }, 336 { 337 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7, 338 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 339 }, 340 // fill in 8 addresses starting from address 40 341 { 342 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0, 343 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 344 }, 345 { 346 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1, 347 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 348 }, 349 { 350 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2, 351 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 352 }, 353 { 354 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3, 355 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 356 }, 357 { 358 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4, 359 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 360 }, 361 { 362 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5, 363 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 364 }, 365 { 366 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6, 367 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 368 }, 369 { 370 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7, 371 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFF0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 372 }, 373 374 // Insert new sequence 375 { 376 &sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0, 377 &sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}, 378 }, 379 { 380 &sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}, 8, 1, 381 &sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 5}}}, 382 }, 383 384 // Merge affected with next 385 { 386 &sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 2, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7, 387 &sequence{block: 0xffffffff, count: 8, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 388 }, 389 { 390 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffc, count: 1, next: &sequence{block: 0xfffffffe, count: 6}}}, 7, 6, 391 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 7}}, 392 }, 393 394 // Merge affected with next and next.next 395 { 396 &sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7, 397 &sequence{block: 0xffffffff, count: 9}, 398 }, 399 { 400 &sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1}}, 31, 7, 401 &sequence{block: 0xffffffff, count: 8}, 402 }, 403 404 // Merge affected with previous and next 405 { 406 &sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7, 407 &sequence{block: 0xffffffff, count: 9}, 408 }, 409 410 // Redundant push: No change 411 {&sequence{block: 0xffff0000, count: 1}, 0, 0, &sequence{block: 0xffff0000, count: 1}}, 412 {&sequence{block: 0xffff0000, count: 7}, 25, 7, &sequence{block: 0xffff0000, count: 7}}, 413 { 414 &sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 7, 7, 415 &sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 416 }, 417 418 // Set last bit 419 {&sequence{block: 0x0, count: 8}, 31, 7, &sequence{block: 0x0, count: 7, next: &sequence{block: 0x1, count: 1}}}, 420 421 // Set bit in a middle sequence in the first block, first bit 422 { 423 &sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0, 424 &sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{ 425 block: 0x0, count: 5, 426 next: &sequence{block: 0x1, count: 1}, 427 }}}, 428 }, 429 430 // Set bit in a middle sequence in the first block, first bit (merge involved) 431 { 432 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0, 433 &sequence{block: 0x80000000, count: 2, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1}}}, 434 }, 435 436 // Set bit in a middle sequence in the first block, last bit 437 { 438 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 31, 439 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x1, count: 1, next: &sequence{ 440 block: 0x0, count: 5, 441 next: &sequence{block: 0x1, count: 1}, 442 }}}, 443 }, 444 445 // Set bit in a middle sequence in the first block, middle bit 446 { 447 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 16, 448 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x8000, count: 1, next: &sequence{ 449 block: 0x0, count: 5, 450 next: &sequence{block: 0x1, count: 1}, 451 }}}, 452 }, 453 454 // Set bit in a middle sequence in a middle block, first bit 455 { 456 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 0, 457 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{ 458 block: 0x80000000, count: 1, 459 next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}, 460 }}}, 461 }, 462 463 // Set bit in a middle sequence in a middle block, last bit 464 { 465 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 31, 466 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{ 467 block: 0x1, count: 1, 468 next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}, 469 }}}, 470 }, 471 472 // Set bit in a middle sequence in a middle block, middle bit 473 { 474 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 15, 475 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{ 476 block: 0x10000, count: 1, 477 next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}, 478 }}}, 479 }, 480 481 // Set bit in a middle sequence in the last block, first bit 482 { 483 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 0, 484 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{ 485 block: 0x80000000, count: 1, 486 next: &sequence{block: 0x1, count: 1}, 487 }}}, 488 }, 489 490 // Set bit in a middle sequence in the last block, last bit 491 { 492 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x4, count: 1}}}, 24, 31, 493 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{ 494 block: 0x1, count: 1, 495 next: &sequence{block: 0x4, count: 1}, 496 }}}, 497 }, 498 499 // Set bit in a middle sequence in the last block, last bit (merge involved) 500 { 501 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 31, 502 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 2}}}, 503 }, 504 505 // Set bit in a middle sequence in the last block, middle bit 506 { 507 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 16, 508 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{ 509 block: 0x8000, count: 1, 510 next: &sequence{block: 0x1, count: 1}, 511 }}}, 512 }, 513 } 514 515 for n, i := range input { 516 mask := pushReservation(i.bytePos, i.bitPos, i.mask, false) 517 if !mask.equal(i.newMask) { 518 t.Fatalf("Error in (%d) pushReservation():\n%s + (%d,%d):\nExp: %s\nGot: %s,", 519 n, i.mask.toString(), i.bytePos, i.bitPos, i.newMask.toString(), mask.toString()) 520 } 521 } 522 } 523 524 func TestSerializeDeserialize(t *testing.T) { 525 s := getTestSequence() 526 527 data, err := s.toByteArray() 528 if err != nil { 529 t.Fatal(err) 530 } 531 532 r := &sequence{} 533 err = r.fromByteArray(data) 534 if err != nil { 535 t.Fatal(err) 536 } 537 538 if !s.equal(r) { 539 t.Fatalf("Sequences are different: \n%v\n%v", s, r) 540 } 541 } 542 543 func getTestSequence() *sequence { 544 // Returns a custom sequence of 1024 * 32 bits 545 return &sequence{ 546 block: 0xFFFFFFFF, 547 count: 100, 548 next: &sequence{ 549 block: 0xFFFFFFFE, 550 count: 1, 551 next: &sequence{ 552 block: 0xFF000000, 553 count: 10, 554 next: &sequence{ 555 block: 0xFFFFFFFF, 556 count: 50, 557 next: &sequence{ 558 block: 0xFFFFFFFC, 559 count: 1, 560 next: &sequence{ 561 block: 0xFF800000, 562 count: 1, 563 next: &sequence{ 564 block: 0xFFFFFFFF, 565 count: 87, 566 next: &sequence{ 567 block: 0x0, 568 count: 150, 569 next: &sequence{ 570 block: 0xFFFFFFFF, 571 count: 200, 572 next: &sequence{ 573 block: 0x0000FFFF, 574 count: 1, 575 next: &sequence{ 576 block: 0x0, 577 count: 399, 578 next: &sequence{ 579 block: 0xFFFFFFFF, 580 count: 23, 581 next: &sequence{ 582 block: 0x1, 583 count: 1, 584 }, 585 }, 586 }, 587 }, 588 }, 589 }, 590 }, 591 }, 592 }, 593 }, 594 }, 595 }, 596 } 597 } 598 599 func TestSet(t *testing.T) { 600 hnd := New(1024 * 32) 601 hnd.head = getTestSequence() 602 603 firstAv := uint64(32*100 + 31) 604 last := uint64(1024*32 - 1) 605 606 if hnd.IsSet(100000) { 607 t.Fatal("IsSet() returned wrong result") 608 } 609 610 if !hnd.IsSet(0) { 611 t.Fatal("IsSet() returned wrong result") 612 } 613 614 if hnd.IsSet(firstAv) { 615 t.Fatal("IsSet() returned wrong result") 616 } 617 618 if !hnd.IsSet(last) { 619 t.Fatal("IsSet() returned wrong result") 620 } 621 622 if err := hnd.Set(0); err == nil { 623 t.Fatal("Expected failure, but succeeded") 624 } 625 626 os, err := hnd.SetAny(false) 627 if err != nil { 628 t.Fatalf("Unexpected failure: %v", err) 629 } 630 if os != firstAv { 631 t.Fatalf("SetAny returned unexpected ordinal. Expected %d. Got %d.", firstAv, os) 632 } 633 if !hnd.IsSet(firstAv) { 634 t.Fatal("IsSet() returned wrong result") 635 } 636 637 if err := hnd.Unset(firstAv); err != nil { 638 t.Fatalf("Unexpected failure: %v", err) 639 } 640 641 if hnd.IsSet(firstAv) { 642 t.Fatal("IsSet() returned wrong result") 643 } 644 645 if err := hnd.Set(firstAv); err != nil { 646 t.Fatalf("Unexpected failure: %v", err) 647 } 648 649 if err := hnd.Set(last); err == nil { 650 t.Fatal("Expected failure, but succeeded") 651 } 652 } 653 654 func TestSetUnset(t *testing.T) { 655 numBits := uint64(32 * blockLen) 656 hnd := New(numBits) 657 658 if err := hnd.Set(uint64(32 * blockLen)); err == nil { 659 t.Fatal("Expected failure, but succeeded") 660 } 661 if err := hnd.Unset(uint64(32 * blockLen)); err == nil { 662 t.Fatal("Expected failure, but succeeded") 663 } 664 665 // set and unset all one by one 666 for hnd.Unselected() > 0 { 667 if _, err := hnd.SetAny(false); err != nil { 668 t.Fatal(err) 669 } 670 } 671 if _, err := hnd.SetAny(false); err != ErrNoBitAvailable { 672 t.Fatal("Expected error. Got success") 673 } 674 if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable { 675 t.Fatal("Expected error. Got success") 676 } 677 if err := hnd.Set(50); err != ErrBitAllocated { 678 t.Fatalf("Expected error. Got %v: %s", err, hnd) 679 } 680 i := uint64(0) 681 for hnd.Unselected() < numBits { 682 if err := hnd.Unset(i); err != nil { 683 t.Fatal(err) 684 } 685 i++ 686 } 687 } 688 689 func TestOffsetSetUnset(t *testing.T) { 690 numBits := uint64(32 * blockLen) 691 hnd := New(numBits) 692 693 // set and unset all one by one 694 for hnd.Unselected() > 0 { 695 if _, err := hnd.SetAny(false); err != nil { 696 t.Fatal(err) 697 } 698 } 699 700 if _, err := hnd.SetAny(false); err != ErrNoBitAvailable { 701 t.Fatal("Expected error. Got success") 702 } 703 704 if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable { 705 t.Fatal("Expected error. Got success") 706 } 707 708 if err := hnd.Unset(288); err != nil { 709 t.Fatal(err) 710 } 711 712 // At this point sequence is (0xffffffff, 9)->(0x7fffffff, 1)->(0xffffffff, 22)->end 713 o, err := hnd.SetAnyInRange(32, 500, false) 714 if err != nil { 715 t.Fatal(err) 716 } 717 718 if o != 288 { 719 t.Fatalf("Expected ordinal not received, Received:%d", o) 720 } 721 } 722 723 func TestSetInRange(t *testing.T) { 724 numBits := uint64(1024 * blockLen) 725 hnd := New(numBits) 726 hnd.head = getTestSequence() 727 728 firstAv := uint64(100*blockLen + blockLen - 1) 729 730 if o, err := hnd.SetAnyInRange(4, 3, false); err == nil { 731 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 732 } 733 734 if o, err := hnd.SetAnyInRange(0, numBits, false); err == nil { 735 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 736 } 737 738 o, err := hnd.SetAnyInRange(100*uint64(blockLen), 101*uint64(blockLen), false) 739 if err != nil { 740 t.Fatalf("Unexpected failure: (%d, %v)", o, err) 741 } 742 if o != firstAv { 743 t.Fatalf("Unexpected ordinal: %d", o) 744 } 745 746 if o, err := hnd.SetAnyInRange(0, uint64(blockLen), false); err == nil { 747 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 748 } 749 750 if o, err := hnd.SetAnyInRange(0, firstAv-1, false); err == nil { 751 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 752 } 753 754 if o, err := hnd.SetAnyInRange(111*uint64(blockLen), 161*uint64(blockLen), false); err == nil { 755 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 756 } 757 758 o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false) 759 if err != nil { 760 t.Fatal(err) 761 } 762 if o != 161*uint64(blockLen)+30 { 763 t.Fatalf("Unexpected ordinal: %d", o) 764 } 765 766 o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false) 767 if err != nil { 768 t.Fatal(err) 769 } 770 if o != 161*uint64(blockLen)+31 { 771 t.Fatalf("Unexpected ordinal: %d", o) 772 } 773 774 o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false) 775 if err == nil { 776 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 777 } 778 779 if _, err := hnd.SetAnyInRange(0, numBits-1, false); err != nil { 780 t.Fatalf("Unexpected failure: %v", err) 781 } 782 783 // set one bit using the set range with 1 bit size range 784 if _, err := hnd.SetAnyInRange(uint64(163*blockLen-1), uint64(163*blockLen-1), false); err != nil { 785 t.Fatal(err) 786 } 787 788 // create a non multiple of 32 mask 789 hnd = New(30) 790 791 // set all bit in the first range 792 for hnd.Unselected() > 22 { 793 if o, err := hnd.SetAnyInRange(0, 7, false); err != nil { 794 t.Fatalf("Unexpected failure: (%d, %v)", o, err) 795 } 796 } 797 // try one more set, which should fail 798 o, err = hnd.SetAnyInRange(0, 7, false) 799 if err == nil { 800 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 801 } 802 if err != ErrNoBitAvailable { 803 t.Fatalf("Unexpected error: %v", err) 804 } 805 806 // set all bit in a second range 807 for hnd.Unselected() > 14 { 808 if o, err := hnd.SetAnyInRange(8, 15, false); err != nil { 809 t.Fatalf("Unexpected failure: (%d, %v)", o, err) 810 } 811 } 812 813 // try one more set, which should fail 814 o, err = hnd.SetAnyInRange(0, 15, false) 815 if err == nil { 816 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 817 } 818 if err != ErrNoBitAvailable { 819 t.Fatalf("Unexpected error: %v", err) 820 } 821 822 // set all bit in a range which includes the last bit 823 for hnd.Unselected() > 12 { 824 if o, err := hnd.SetAnyInRange(28, 29, false); err != nil { 825 t.Fatalf("Unexpected failure: (%d, %v)", o, err) 826 } 827 } 828 o, err = hnd.SetAnyInRange(28, 29, false) 829 if err == nil { 830 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 831 } 832 if err != ErrNoBitAvailable { 833 t.Fatalf("Unexpected error: %v", err) 834 } 835 } 836 837 // This one tests an allocation pattern which unveiled an issue in pushReservation 838 // Specifically a failure in detecting when we are in the (B) case (the bit to set 839 // belongs to the last block of the current sequence). Because of a bug, code 840 // was assuming the bit belonged to a block in the middle of the current sequence. 841 // Which in turn caused an incorrect allocation when requesting a bit which is not 842 // in the first or last sequence block. 843 func TestSetAnyInRange(t *testing.T) { 844 numBits := uint64(8 * blockLen) 845 hnd := New(numBits) 846 847 if err := hnd.Set(0); err != nil { 848 t.Fatal(err) 849 } 850 851 if err := hnd.Set(255); err != nil { 852 t.Fatal(err) 853 } 854 855 o, err := hnd.SetAnyInRange(128, 255, false) 856 if err != nil { 857 t.Fatal(err) 858 } 859 if o != 128 { 860 t.Fatalf("Unexpected ordinal: %d", o) 861 } 862 863 o, err = hnd.SetAnyInRange(128, 255, false) 864 if err != nil { 865 t.Fatal(err) 866 } 867 868 if o != 129 { 869 t.Fatalf("Unexpected ordinal: %d", o) 870 } 871 872 o, err = hnd.SetAnyInRange(246, 255, false) 873 if err != nil { 874 t.Fatal(err) 875 } 876 if o != 246 { 877 t.Fatalf("Unexpected ordinal: %d", o) 878 } 879 880 o, err = hnd.SetAnyInRange(246, 255, false) 881 if err != nil { 882 t.Fatal(err) 883 } 884 if o != 247 { 885 t.Fatalf("Unexpected ordinal: %d", o) 886 } 887 } 888 889 func TestMethods(t *testing.T) { 890 numBits := uint64(256 * blockLen) 891 hnd := New(numBits) 892 893 if hnd.Bits() != numBits { 894 t.Fatalf("Unexpected bit number: %d", hnd.Bits()) 895 } 896 897 if hnd.Unselected() != numBits { 898 t.Fatalf("Unexpected bit number: %d", hnd.Unselected()) 899 } 900 901 exp := "(0x0, 256)->end" 902 if hnd.head.toString() != exp { 903 t.Fatalf("Unexpected sequence string: %s", hnd.head.toString()) 904 } 905 906 for i := 0; i < 192; i++ { 907 _, err := hnd.SetAny(false) 908 if err != nil { 909 t.Fatal(err) 910 } 911 } 912 913 exp = "(0xffffffff, 6)->(0x0, 250)->end" 914 if hnd.head.toString() != exp { 915 t.Fatalf("Unexpected sequence string: %s", hnd.head.toString()) 916 } 917 } 918 919 func TestRandomAllocateDeallocate(t *testing.T) { 920 numBits := int(16 * blockLen) 921 hnd := New(uint64(numBits)) 922 923 seed := time.Now().Unix() 924 rng := rand.New(rand.NewSource(seed)) 925 926 // Allocate all bits using a random pattern 927 pattern := rng.Perm(numBits) 928 for _, bit := range pattern { 929 err := hnd.Set(uint64(bit)) 930 if err != nil { 931 t.Fatalf("Unexpected failure on allocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 932 } 933 } 934 if hnd.Unselected() != 0 { 935 t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd) 936 } 937 if hnd.head.toString() != "(0xffffffff, 16)->end" { 938 t.Fatalf("Unexpected db: %s", hnd.head.toString()) 939 } 940 941 // Deallocate all bits using a random pattern 942 pattern = rng.Perm(numBits) 943 for _, bit := range pattern { 944 err := hnd.Unset(uint64(bit)) 945 if err != nil { 946 t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 947 } 948 } 949 if hnd.Unselected() != uint64(numBits) { 950 t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd) 951 } 952 if hnd.head.toString() != "(0x0, 16)->end" { 953 t.Fatalf("Unexpected db: %s", hnd.head.toString()) 954 } 955 } 956 957 func TestAllocateRandomDeallocate(t *testing.T) { 958 numBlocks := uint32(8) 959 numBits := int(numBlocks * blockLen) 960 hnd := New(uint64(numBits)) 961 962 expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}} 963 964 // Allocate first half of the bits 965 for i := 0; i < numBits/2; i++ { 966 _, err := hnd.SetAny(false) 967 if err != nil { 968 t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd) 969 } 970 } 971 if hnd.Unselected() != uint64(numBits/2) { 972 t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd) 973 } 974 if !hnd.head.equal(expected) { 975 t.Fatalf("Unexpected sequence. Got:\n%s", hnd) 976 } 977 978 seed := time.Now().Unix() 979 rng := rand.New(rand.NewSource(seed)) 980 981 // Deallocate half of the allocated bits following a random pattern 982 pattern := rng.Perm(numBits / 2) 983 for i := 0; i < numBits/4; i++ { 984 bit := pattern[i] 985 err := hnd.Unset(uint64(bit)) 986 if err != nil { 987 t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 988 } 989 } 990 if hnd.Unselected() != uint64(3*numBits/4) { 991 t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd) 992 } 993 994 // Request a quarter of bits 995 for i := 0; i < numBits/4; i++ { 996 _, err := hnd.SetAny(false) 997 if err != nil { 998 t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd) 999 } 1000 } 1001 if hnd.Unselected() != uint64(numBits/2) { 1002 t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd) 1003 } 1004 if !hnd.head.equal(expected) { 1005 t.Fatalf("Unexpected sequence. Got:\n%s", hnd) 1006 } 1007 } 1008 1009 func TestAllocateRandomDeallocateSerialize(t *testing.T) { 1010 numBlocks := uint32(8) 1011 numBits := int(numBlocks * blockLen) 1012 hnd := New(uint64(numBits)) 1013 1014 expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}} 1015 1016 // Allocate first half of the bits 1017 for i := 0; i < numBits/2; i++ { 1018 _, err := hnd.SetAny(true) 1019 if err != nil { 1020 t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd) 1021 } 1022 } 1023 1024 if hnd.Unselected() != uint64(numBits/2) { 1025 t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd) 1026 } 1027 if !hnd.head.equal(expected) { 1028 t.Fatalf("Unexpected sequence. Got:\n%s", hnd) 1029 } 1030 1031 seed := time.Now().Unix() 1032 rng := rand.New(rand.NewSource(seed)) 1033 1034 // Deallocate half of the allocated bits following a random pattern 1035 pattern := rng.Perm(numBits / 2) 1036 for i := 0; i < numBits/4; i++ { 1037 bit := pattern[i] 1038 err := hnd.Unset(uint64(bit)) 1039 if err != nil { 1040 t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 1041 } 1042 } 1043 if hnd.Unselected() != uint64(3*numBits/4) { 1044 t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd) 1045 } 1046 1047 // Request a quarter of bits 1048 for i := 0; i < numBits/4; i++ { 1049 _, err := hnd.SetAny(true) 1050 if err != nil { 1051 t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd) 1052 } 1053 } 1054 if hnd.Unselected() != uint64(numBits/2) { 1055 t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd) 1056 } 1057 } 1058 1059 func testSetRollover(t *testing.T, serial bool) { 1060 numBlocks := uint32(8) 1061 numBits := int(numBlocks * blockLen) 1062 hnd := New(uint64(numBits)) 1063 1064 // Allocate first half of the bits 1065 for i := 0; i < numBits/2; i++ { 1066 _, err := hnd.SetAny(serial) 1067 if err != nil { 1068 t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd) 1069 } 1070 } 1071 1072 if hnd.Unselected() != uint64(numBits/2) { 1073 t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd) 1074 } 1075 1076 seed := time.Now().Unix() 1077 rng := rand.New(rand.NewSource(seed)) 1078 1079 // Deallocate half of the allocated bits following a random pattern 1080 pattern := rng.Perm(numBits / 2) 1081 for i := 0; i < numBits/4; i++ { 1082 bit := pattern[i] 1083 err := hnd.Unset(uint64(bit)) 1084 if err != nil { 1085 t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 1086 } 1087 } 1088 if hnd.Unselected() != uint64(3*numBits/4) { 1089 t.Fatalf("Unexpected free bits: found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd) 1090 } 1091 1092 // request to allocate for remaining half of the bits 1093 for i := 0; i < numBits/2; i++ { 1094 _, err := hnd.SetAny(serial) 1095 if err != nil { 1096 t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd) 1097 } 1098 } 1099 1100 // At this point all the bits must be allocated except the randomly unallocated bits 1101 // which were unallocated in the first half of the bit sequence 1102 if hnd.Unselected() != uint64(numBits/4) { 1103 t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), numBits/4) 1104 } 1105 1106 for i := 0; i < numBits/4; i++ { 1107 _, err := hnd.SetAny(serial) 1108 if err != nil { 1109 t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd) 1110 } 1111 } 1112 // Now requesting to allocate the unallocated random bits (qurter of the number of bits) should 1113 // leave no more bits that can be allocated. 1114 if hnd.Unselected() != 0 { 1115 t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), 0) 1116 } 1117 } 1118 1119 func TestSetRollover(t *testing.T) { 1120 testSetRollover(t, false) 1121 } 1122 1123 func TestSetRolloverSerial(t *testing.T) { 1124 testSetRollover(t, true) 1125 } 1126 1127 func TestGetFirstAvailableFromCurrent(t *testing.T) { 1128 input := []struct { 1129 mask *sequence 1130 bytePos uint64 1131 bitPos uint64 1132 start uint64 1133 curr uint64 1134 end uint64 1135 }{ 1136 {&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos, 0, 0, 65536}, 1137 {&sequence{block: 0x0, count: 8}, 0, 0, 0, 0, 256}, 1138 {&sequence{block: 0x80000000, count: 8}, 1, 0, 0, 8, 256}, 1139 {&sequence{block: 0xC0000000, count: 8}, 0, 2, 0, 2, 256}, 1140 {&sequence{block: 0xE0000000, count: 8}, 0, 3, 0, 0, 256}, 1141 {&sequence{block: 0xFFFB1FFF, count: 8}, 2, 0, 14, 0, 256}, 1142 {&sequence{block: 0xFFFFFFFE, count: 8}, 3, 7, 0, 0, 256}, 1143 1144 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 14}}}, 4, 0, 0, 32, 512}, 1145 {&sequence{block: 0xfffeffff, count: 1, next: &sequence{block: 0xffffffff, count: 15}}, 1, 7, 0, 16, 512}, 1146 {&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 5, 7, 0, 16, 512}, 1147 {&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 9, 7, 0, 48, 512}, 1148 {&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xffffffef, count: 14}}, 19, 3, 0, 124, 512}, 1149 {&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0x0fffffff, count: 1}}, 60, 0, 0, 480, 512}, 1150 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 17, 7, 0, 124, 512}, 1151 {&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xffffffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 3, 5, 0, 124, 512}, 1152 {&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 13, 7, 0, 80, 512}, 1153 } 1154 1155 for n, i := range input { 1156 bytePos, bitPos, _ := getAvailableFromCurrent(i.mask, i.start, i.curr, i.end) 1157 if bytePos != i.bytePos || bitPos != i.bitPos { 1158 t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos) 1159 } 1160 } 1161 } 1162 1163 func TestMarshalJSON(t *testing.T) { 1164 expected := []byte("hello libnetwork") 1165 hnd := New(uint64(len(expected) * 8)) 1166 1167 for i, c := range expected { 1168 for j := 0; j < 8; j++ { 1169 if c&(1<<j) == 0 { 1170 continue 1171 } 1172 if err := hnd.Set(uint64(i*8 + j)); err != nil { 1173 t.Fatal(err) 1174 } 1175 } 1176 } 1177 1178 hstr := hnd.String() 1179 t.Log(hstr) 1180 marshaled, err := hnd.MarshalJSON() 1181 if err != nil { 1182 t.Fatalf("MarshalJSON() err = %v", err) 1183 } 1184 t.Logf("%s", marshaled) 1185 1186 // Serializations of hnd as would be marshaled by versions of the code 1187 // found in the wild. We need to support unmarshaling old versions to 1188 // maintain backwards compatibility with sequences persisted on disk. 1189 const ( 1190 goldenV0 = `"AAAAAAAAAIAAAAAAAAAAPRamNjYAAAAAAAAAAfYENpYAAAAAAAAAAUZ2pi4AAAAAAAAAAe72TtYAAAAAAAAAAQ=="` 1191 ) 1192 1193 if string(marshaled) != goldenV0 { 1194 t.Errorf("MarshalJSON() output differs from golden. Please add a new golden case to this test.") 1195 } 1196 1197 for _, tt := range []struct { 1198 name string 1199 data []byte 1200 }{ 1201 {name: "Live", data: marshaled}, 1202 {name: "Golden-v0", data: []byte(goldenV0)}, 1203 } { 1204 tt := tt 1205 t.Run("UnmarshalJSON="+tt.name, func(t *testing.T) { 1206 hnd2 := New(0) 1207 if err := hnd2.UnmarshalJSON(tt.data); err != nil { 1208 t.Errorf("UnmarshalJSON() err = %v", err) 1209 } 1210 1211 h2str := hnd2.String() 1212 t.Log(h2str) 1213 if hstr != h2str { 1214 t.Errorf("Unmarshaled a different bitmap: want %q, got %q", hstr, h2str) 1215 } 1216 }) 1217 } 1218 }