github.com/rawahars/moby@v24.0.4+incompatible/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 {&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5, next: &sequence{block: 0xFF, count: 1}}}}, 263 &sequence{block: 0xFE, count: 14, next: &sequence{block: 0xFF, count: 1}}}, 264 265 // No merge 266 {&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}}, 267 &sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}}}, 268 269 // 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 270 {&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 1, next: &sequence{block: 0xFF, count: 5}}}, 271 &sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 6}}}, 272 } 273 274 for n, i := range input { 275 mergeSequences(i.original) 276 for !i.merged.equal(i.original) { 277 t.Fatalf("Error in (%d) mergeSequences().\nExp: %s\nGot: %s,", n, i.merged.toString(), i.original.toString()) 278 } 279 } 280 } 281 282 func TestPushReservation(t *testing.T) { 283 input := []struct { 284 mask *sequence 285 bytePos uint64 286 bitPos uint64 287 newMask *sequence 288 }{ 289 // Create first sequence and fill in 8 addresses starting from address 0 290 {&sequence{block: 0x0, count: 8, next: nil}, 0, 0, &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}}, 291 {&sequence{block: 0x80000000, count: 8}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x80000000, count: 7, next: nil}}}, 292 {&sequence{block: 0xC0000000, count: 8}, 0, 2, &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xC0000000, count: 7, next: nil}}}, 293 {&sequence{block: 0xE0000000, count: 8}, 0, 3, &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xE0000000, count: 7, next: nil}}}, 294 {&sequence{block: 0xF0000000, count: 8}, 0, 4, &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xF0000000, count: 7, next: nil}}}, 295 {&sequence{block: 0xF8000000, count: 8}, 0, 5, &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xF8000000, count: 7, next: nil}}}, 296 {&sequence{block: 0xFC000000, count: 8}, 0, 6, &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xFC000000, count: 7, next: nil}}}, 297 {&sequence{block: 0xFE000000, count: 8}, 0, 7, &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xFE000000, count: 7, next: nil}}}, 298 299 {&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}}}, 300 301 // Create second sequence and fill in 8 addresses starting from address 32 302 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6, next: nil}}}, 4, 0, 303 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 304 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1, 305 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 306 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2, 307 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 308 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3, 309 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 310 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4, 311 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 312 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5, 313 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 314 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6, 315 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 316 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7, 317 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 318 // fill in 8 addresses starting from address 40 319 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0, 320 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 321 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1, 322 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 323 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2, 324 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 325 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3, 326 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 327 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4, 328 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 329 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5, 330 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 331 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6, 332 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 333 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7, 334 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFF0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}}, 335 336 // Insert new sequence 337 {&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0, 338 &sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}}, 339 {&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}, 8, 1, 340 &sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 5}}}}, 341 342 // Merge affected with next 343 {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 2, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7, 344 &sequence{block: 0xffffffff, count: 8, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}}, 345 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffc, count: 1, next: &sequence{block: 0xfffffffe, count: 6}}}, 7, 6, 346 &sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 7}}}, 347 348 // Merge affected with next and next.next 349 {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7, 350 &sequence{block: 0xffffffff, count: 9}}, 351 {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1}}, 31, 7, 352 &sequence{block: 0xffffffff, count: 8}}, 353 354 // Merge affected with previous and next 355 {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7, 356 &sequence{block: 0xffffffff, count: 9}}, 357 358 // Redundant push: No change 359 {&sequence{block: 0xffff0000, count: 1}, 0, 0, &sequence{block: 0xffff0000, count: 1}}, 360 {&sequence{block: 0xffff0000, count: 7}, 25, 7, &sequence{block: 0xffff0000, count: 7}}, 361 {&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 7, 7, 362 &sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}}, 363 364 // Set last bit 365 {&sequence{block: 0x0, count: 8}, 31, 7, &sequence{block: 0x0, count: 7, next: &sequence{block: 0x1, count: 1}}}, 366 367 // Set bit in a middle sequence in the first block, first bit 368 {&sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0, 369 &sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, 370 next: &sequence{block: 0x1, count: 1}}}}}, 371 372 // Set bit in a middle sequence in the first block, first bit (merge involved) 373 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0, 374 &sequence{block: 0x80000000, count: 2, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1}}}}, 375 376 // Set bit in a middle sequence in the first block, last bit 377 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 31, 378 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x1, count: 1, next: &sequence{block: 0x0, count: 5, 379 next: &sequence{block: 0x1, count: 1}}}}}, 380 381 // Set bit in a middle sequence in the first block, middle bit 382 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 16, 383 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x8000, count: 1, next: &sequence{block: 0x0, count: 5, 384 next: &sequence{block: 0x1, count: 1}}}}}, 385 386 // Set bit in a middle sequence in a middle block, first bit 387 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 0, 388 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x80000000, count: 1, 389 next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}}, 390 391 // Set bit in a middle sequence in a middle block, last bit 392 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 31, 393 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x1, count: 1, 394 next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}}, 395 396 // Set bit in a middle sequence in a middle block, middle bit 397 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 15, 398 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x10000, count: 1, 399 next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}}, 400 401 // Set bit in a middle sequence in the last block, first bit 402 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 0, 403 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x80000000, count: 1, 404 next: &sequence{block: 0x1, count: 1}}}}}, 405 406 // Set bit in a middle sequence in the last block, last bit 407 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x4, count: 1}}}, 24, 31, 408 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1, 409 next: &sequence{block: 0x4, count: 1}}}}}, 410 411 // Set bit in a middle sequence in the last block, last bit (merge involved) 412 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 31, 413 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 2}}}}, 414 415 // Set bit in a middle sequence in the last block, middle bit 416 {&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 16, 417 &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x8000, count: 1, 418 next: &sequence{block: 0x1, count: 1}}}}}, 419 } 420 421 for n, i := range input { 422 mask := pushReservation(i.bytePos, i.bitPos, i.mask, false) 423 if !mask.equal(i.newMask) { 424 t.Fatalf("Error in (%d) pushReservation():\n%s + (%d,%d):\nExp: %s\nGot: %s,", 425 n, i.mask.toString(), i.bytePos, i.bitPos, i.newMask.toString(), mask.toString()) 426 } 427 } 428 } 429 430 func TestSerializeDeserialize(t *testing.T) { 431 s := getTestSequence() 432 433 data, err := s.toByteArray() 434 if err != nil { 435 t.Fatal(err) 436 } 437 438 r := &sequence{} 439 err = r.fromByteArray(data) 440 if err != nil { 441 t.Fatal(err) 442 } 443 444 if !s.equal(r) { 445 t.Fatalf("Sequences are different: \n%v\n%v", s, r) 446 } 447 } 448 449 func getTestSequence() *sequence { 450 // Returns a custom sequence of 1024 * 32 bits 451 return &sequence{ 452 block: 0xFFFFFFFF, 453 count: 100, 454 next: &sequence{ 455 block: 0xFFFFFFFE, 456 count: 1, 457 next: &sequence{ 458 block: 0xFF000000, 459 count: 10, 460 next: &sequence{ 461 block: 0xFFFFFFFF, 462 count: 50, 463 next: &sequence{ 464 block: 0xFFFFFFFC, 465 count: 1, 466 next: &sequence{ 467 block: 0xFF800000, 468 count: 1, 469 next: &sequence{ 470 block: 0xFFFFFFFF, 471 count: 87, 472 next: &sequence{ 473 block: 0x0, 474 count: 150, 475 next: &sequence{ 476 block: 0xFFFFFFFF, 477 count: 200, 478 next: &sequence{ 479 block: 0x0000FFFF, 480 count: 1, 481 next: &sequence{ 482 block: 0x0, 483 count: 399, 484 next: &sequence{ 485 block: 0xFFFFFFFF, 486 count: 23, 487 next: &sequence{ 488 block: 0x1, 489 count: 1, 490 }, 491 }, 492 }, 493 }, 494 }, 495 }, 496 }, 497 }, 498 }, 499 }, 500 }, 501 }, 502 } 503 } 504 505 func TestSet(t *testing.T) { 506 hnd := New(1024 * 32) 507 hnd.head = getTestSequence() 508 509 firstAv := uint64(32*100 + 31) 510 last := uint64(1024*32 - 1) 511 512 if hnd.IsSet(100000) { 513 t.Fatal("IsSet() returned wrong result") 514 } 515 516 if !hnd.IsSet(0) { 517 t.Fatal("IsSet() returned wrong result") 518 } 519 520 if hnd.IsSet(firstAv) { 521 t.Fatal("IsSet() returned wrong result") 522 } 523 524 if !hnd.IsSet(last) { 525 t.Fatal("IsSet() returned wrong result") 526 } 527 528 if err := hnd.Set(0); err == nil { 529 t.Fatal("Expected failure, but succeeded") 530 } 531 532 os, err := hnd.SetAny(false) 533 if err != nil { 534 t.Fatalf("Unexpected failure: %v", err) 535 } 536 if os != firstAv { 537 t.Fatalf("SetAny returned unexpected ordinal. Expected %d. Got %d.", firstAv, os) 538 } 539 if !hnd.IsSet(firstAv) { 540 t.Fatal("IsSet() returned wrong result") 541 } 542 543 if err := hnd.Unset(firstAv); err != nil { 544 t.Fatalf("Unexpected failure: %v", err) 545 } 546 547 if hnd.IsSet(firstAv) { 548 t.Fatal("IsSet() returned wrong result") 549 } 550 551 if err := hnd.Set(firstAv); err != nil { 552 t.Fatalf("Unexpected failure: %v", err) 553 } 554 555 if err := hnd.Set(last); err == nil { 556 t.Fatal("Expected failure, but succeeded") 557 } 558 } 559 560 func TestSetUnset(t *testing.T) { 561 numBits := uint64(32 * blockLen) 562 hnd := New(numBits) 563 564 if err := hnd.Set(uint64(32 * blockLen)); err == nil { 565 t.Fatal("Expected failure, but succeeded") 566 } 567 if err := hnd.Unset(uint64(32 * blockLen)); err == nil { 568 t.Fatal("Expected failure, but succeeded") 569 } 570 571 // set and unset all one by one 572 for hnd.Unselected() > 0 { 573 if _, err := hnd.SetAny(false); err != nil { 574 t.Fatal(err) 575 } 576 } 577 if _, err := hnd.SetAny(false); err != ErrNoBitAvailable { 578 t.Fatal("Expected error. Got success") 579 } 580 if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable { 581 t.Fatal("Expected error. Got success") 582 } 583 if err := hnd.Set(50); err != ErrBitAllocated { 584 t.Fatalf("Expected error. Got %v: %s", err, hnd) 585 } 586 i := uint64(0) 587 for hnd.Unselected() < numBits { 588 if err := hnd.Unset(i); err != nil { 589 t.Fatal(err) 590 } 591 i++ 592 } 593 } 594 595 func TestOffsetSetUnset(t *testing.T) { 596 numBits := uint64(32 * blockLen) 597 hnd := New(numBits) 598 599 // set and unset all one by one 600 for hnd.Unselected() > 0 { 601 if _, err := hnd.SetAny(false); err != nil { 602 t.Fatal(err) 603 } 604 } 605 606 if _, err := hnd.SetAny(false); err != ErrNoBitAvailable { 607 t.Fatal("Expected error. Got success") 608 } 609 610 if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable { 611 t.Fatal("Expected error. Got success") 612 } 613 614 if err := hnd.Unset(288); err != nil { 615 t.Fatal(err) 616 } 617 618 //At this point sequence is (0xffffffff, 9)->(0x7fffffff, 1)->(0xffffffff, 22)->end 619 o, err := hnd.SetAnyInRange(32, 500, false) 620 if err != nil { 621 t.Fatal(err) 622 } 623 624 if o != 288 { 625 t.Fatalf("Expected ordinal not received, Received:%d", o) 626 } 627 } 628 629 func TestSetInRange(t *testing.T) { 630 numBits := uint64(1024 * blockLen) 631 hnd := New(numBits) 632 hnd.head = getTestSequence() 633 634 firstAv := uint64(100*blockLen + blockLen - 1) 635 636 if o, err := hnd.SetAnyInRange(4, 3, false); err == nil { 637 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 638 } 639 640 if o, err := hnd.SetAnyInRange(0, numBits, false); err == nil { 641 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 642 } 643 644 o, err := hnd.SetAnyInRange(100*uint64(blockLen), 101*uint64(blockLen), false) 645 if err != nil { 646 t.Fatalf("Unexpected failure: (%d, %v)", o, err) 647 } 648 if o != firstAv { 649 t.Fatalf("Unexpected ordinal: %d", o) 650 } 651 652 if o, err := hnd.SetAnyInRange(0, uint64(blockLen), false); err == nil { 653 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 654 } 655 656 if o, err := hnd.SetAnyInRange(0, firstAv-1, false); err == nil { 657 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 658 } 659 660 if o, err := hnd.SetAnyInRange(111*uint64(blockLen), 161*uint64(blockLen), false); err == nil { 661 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 662 } 663 664 o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false) 665 if err != nil { 666 t.Fatal(err) 667 } 668 if o != 161*uint64(blockLen)+30 { 669 t.Fatalf("Unexpected ordinal: %d", o) 670 } 671 672 o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false) 673 if err != nil { 674 t.Fatal(err) 675 } 676 if o != 161*uint64(blockLen)+31 { 677 t.Fatalf("Unexpected ordinal: %d", o) 678 } 679 680 o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false) 681 if err == nil { 682 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 683 } 684 685 if _, err := hnd.SetAnyInRange(0, numBits-1, false); err != nil { 686 t.Fatalf("Unexpected failure: %v", err) 687 } 688 689 // set one bit using the set range with 1 bit size range 690 if _, err := hnd.SetAnyInRange(uint64(163*blockLen-1), uint64(163*blockLen-1), false); err != nil { 691 t.Fatal(err) 692 } 693 694 // create a non multiple of 32 mask 695 hnd = New(30) 696 697 // set all bit in the first range 698 for hnd.Unselected() > 22 { 699 if o, err := hnd.SetAnyInRange(0, 7, false); err != nil { 700 t.Fatalf("Unexpected failure: (%d, %v)", o, err) 701 } 702 } 703 // try one more set, which should fail 704 o, err = hnd.SetAnyInRange(0, 7, false) 705 if err == nil { 706 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 707 } 708 if err != ErrNoBitAvailable { 709 t.Fatalf("Unexpected error: %v", err) 710 } 711 712 // set all bit in a second range 713 for hnd.Unselected() > 14 { 714 if o, err := hnd.SetAnyInRange(8, 15, false); err != nil { 715 t.Fatalf("Unexpected failure: (%d, %v)", o, err) 716 } 717 } 718 719 // try one more set, which should fail 720 o, err = hnd.SetAnyInRange(0, 15, false) 721 if err == nil { 722 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 723 } 724 if err != ErrNoBitAvailable { 725 t.Fatalf("Unexpected error: %v", err) 726 } 727 728 // set all bit in a range which includes the last bit 729 for hnd.Unselected() > 12 { 730 if o, err := hnd.SetAnyInRange(28, 29, false); err != nil { 731 t.Fatalf("Unexpected failure: (%d, %v)", o, err) 732 } 733 } 734 o, err = hnd.SetAnyInRange(28, 29, false) 735 if err == nil { 736 t.Fatalf("Expected failure. Got success with ordinal:%d", o) 737 } 738 if err != ErrNoBitAvailable { 739 t.Fatalf("Unexpected error: %v", err) 740 } 741 } 742 743 // This one tests an allocation pattern which unveiled an issue in pushReservation 744 // Specifically a failure in detecting when we are in the (B) case (the bit to set 745 // belongs to the last block of the current sequence). Because of a bug, code 746 // was assuming the bit belonged to a block in the middle of the current sequence. 747 // Which in turn caused an incorrect allocation when requesting a bit which is not 748 // in the first or last sequence block. 749 func TestSetAnyInRange(t *testing.T) { 750 numBits := uint64(8 * blockLen) 751 hnd := New(numBits) 752 753 if err := hnd.Set(0); err != nil { 754 t.Fatal(err) 755 } 756 757 if err := hnd.Set(255); err != nil { 758 t.Fatal(err) 759 } 760 761 o, err := hnd.SetAnyInRange(128, 255, false) 762 if err != nil { 763 t.Fatal(err) 764 } 765 if o != 128 { 766 t.Fatalf("Unexpected ordinal: %d", o) 767 } 768 769 o, err = hnd.SetAnyInRange(128, 255, false) 770 if err != nil { 771 t.Fatal(err) 772 } 773 774 if o != 129 { 775 t.Fatalf("Unexpected ordinal: %d", o) 776 } 777 778 o, err = hnd.SetAnyInRange(246, 255, false) 779 if err != nil { 780 t.Fatal(err) 781 } 782 if o != 246 { 783 t.Fatalf("Unexpected ordinal: %d", o) 784 } 785 786 o, err = hnd.SetAnyInRange(246, 255, false) 787 if err != nil { 788 t.Fatal(err) 789 } 790 if o != 247 { 791 t.Fatalf("Unexpected ordinal: %d", o) 792 } 793 } 794 795 func TestMethods(t *testing.T) { 796 numBits := uint64(256 * blockLen) 797 hnd := New(numBits) 798 799 if hnd.Bits() != numBits { 800 t.Fatalf("Unexpected bit number: %d", hnd.Bits()) 801 } 802 803 if hnd.Unselected() != numBits { 804 t.Fatalf("Unexpected bit number: %d", hnd.Unselected()) 805 } 806 807 exp := "(0x0, 256)->end" 808 if hnd.head.toString() != exp { 809 t.Fatalf("Unexpected sequence string: %s", hnd.head.toString()) 810 } 811 812 for i := 0; i < 192; i++ { 813 _, err := hnd.SetAny(false) 814 if err != nil { 815 t.Fatal(err) 816 } 817 } 818 819 exp = "(0xffffffff, 6)->(0x0, 250)->end" 820 if hnd.head.toString() != exp { 821 t.Fatalf("Unexpected sequence string: %s", hnd.head.toString()) 822 } 823 } 824 825 func TestRandomAllocateDeallocate(t *testing.T) { 826 numBits := int(16 * blockLen) 827 hnd := New(uint64(numBits)) 828 829 seed := time.Now().Unix() 830 rng := rand.New(rand.NewSource(seed)) 831 832 // Allocate all bits using a random pattern 833 pattern := rng.Perm(numBits) 834 for _, bit := range pattern { 835 err := hnd.Set(uint64(bit)) 836 if err != nil { 837 t.Fatalf("Unexpected failure on allocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 838 } 839 } 840 if hnd.Unselected() != 0 { 841 t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd) 842 } 843 if hnd.head.toString() != "(0xffffffff, 16)->end" { 844 t.Fatalf("Unexpected db: %s", hnd.head.toString()) 845 } 846 847 // Deallocate all bits using a random pattern 848 pattern = rng.Perm(numBits) 849 for _, bit := range pattern { 850 err := hnd.Unset(uint64(bit)) 851 if err != nil { 852 t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 853 } 854 } 855 if hnd.Unselected() != uint64(numBits) { 856 t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd) 857 } 858 if hnd.head.toString() != "(0x0, 16)->end" { 859 t.Fatalf("Unexpected db: %s", hnd.head.toString()) 860 } 861 } 862 863 func TestAllocateRandomDeallocate(t *testing.T) { 864 numBlocks := uint32(8) 865 numBits := int(numBlocks * blockLen) 866 hnd := New(uint64(numBits)) 867 868 expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}} 869 870 // Allocate first half of the bits 871 for i := 0; i < numBits/2; i++ { 872 _, err := hnd.SetAny(false) 873 if err != nil { 874 t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd) 875 } 876 } 877 if hnd.Unselected() != uint64(numBits/2) { 878 t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd) 879 } 880 if !hnd.head.equal(expected) { 881 t.Fatalf("Unexpected sequence. Got:\n%s", hnd) 882 } 883 884 seed := time.Now().Unix() 885 rng := rand.New(rand.NewSource(seed)) 886 887 // Deallocate half of the allocated bits following a random pattern 888 pattern := rng.Perm(numBits / 2) 889 for i := 0; i < numBits/4; i++ { 890 bit := pattern[i] 891 err := hnd.Unset(uint64(bit)) 892 if err != nil { 893 t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 894 } 895 } 896 if hnd.Unselected() != uint64(3*numBits/4) { 897 t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd) 898 } 899 900 // Request a quarter of bits 901 for i := 0; i < numBits/4; i++ { 902 _, err := hnd.SetAny(false) 903 if err != nil { 904 t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd) 905 } 906 } 907 if hnd.Unselected() != uint64(numBits/2) { 908 t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd) 909 } 910 if !hnd.head.equal(expected) { 911 t.Fatalf("Unexpected sequence. Got:\n%s", hnd) 912 } 913 } 914 915 func TestAllocateRandomDeallocateSerialize(t *testing.T) { 916 917 numBlocks := uint32(8) 918 numBits := int(numBlocks * blockLen) 919 hnd := New(uint64(numBits)) 920 921 expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}} 922 923 // Allocate first half of the bits 924 for i := 0; i < numBits/2; i++ { 925 _, err := hnd.SetAny(true) 926 if err != nil { 927 t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd) 928 } 929 } 930 931 if hnd.Unselected() != uint64(numBits/2) { 932 t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd) 933 } 934 if !hnd.head.equal(expected) { 935 t.Fatalf("Unexpected sequence. Got:\n%s", hnd) 936 } 937 938 seed := time.Now().Unix() 939 rng := rand.New(rand.NewSource(seed)) 940 941 // Deallocate half of the allocated bits following a random pattern 942 pattern := rng.Perm(numBits / 2) 943 for i := 0; i < numBits/4; i++ { 944 bit := pattern[i] 945 err := hnd.Unset(uint64(bit)) 946 if err != nil { 947 t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 948 } 949 } 950 if hnd.Unselected() != uint64(3*numBits/4) { 951 t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd) 952 } 953 954 // Request a quarter of bits 955 for i := 0; i < numBits/4; i++ { 956 _, err := hnd.SetAny(true) 957 if err != nil { 958 t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd) 959 } 960 } 961 if hnd.Unselected() != uint64(numBits/2) { 962 t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd) 963 } 964 } 965 966 func testSetRollover(t *testing.T, serial bool) { 967 numBlocks := uint32(8) 968 numBits := int(numBlocks * blockLen) 969 hnd := New(uint64(numBits)) 970 971 // Allocate first half of the bits 972 for i := 0; i < numBits/2; i++ { 973 _, err := hnd.SetAny(serial) 974 if err != nil { 975 t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd) 976 } 977 } 978 979 if hnd.Unselected() != uint64(numBits/2) { 980 t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd) 981 } 982 983 seed := time.Now().Unix() 984 rng := rand.New(rand.NewSource(seed)) 985 986 // Deallocate half of the allocated bits following a random pattern 987 pattern := rng.Perm(numBits / 2) 988 for i := 0; i < numBits/4; i++ { 989 bit := pattern[i] 990 err := hnd.Unset(uint64(bit)) 991 if err != nil { 992 t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd) 993 } 994 } 995 if hnd.Unselected() != uint64(3*numBits/4) { 996 t.Fatalf("Unexpected free bits: found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd) 997 } 998 999 //request to allocate for remaining half of the bits 1000 for i := 0; i < numBits/2; i++ { 1001 _, err := hnd.SetAny(serial) 1002 if err != nil { 1003 t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd) 1004 } 1005 } 1006 1007 //At this point all the bits must be allocated except the randomly unallocated bits 1008 //which were unallocated in the first half of the bit sequence 1009 if hnd.Unselected() != uint64(numBits/4) { 1010 t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), numBits/4) 1011 } 1012 1013 for i := 0; i < numBits/4; i++ { 1014 _, err := hnd.SetAny(serial) 1015 if err != nil { 1016 t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd) 1017 } 1018 } 1019 //Now requesting to allocate the unallocated random bits (qurter of the number of bits) should 1020 //leave no more bits that can be allocated. 1021 if hnd.Unselected() != 0 { 1022 t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), 0) 1023 } 1024 } 1025 1026 func TestSetRollover(t *testing.T) { 1027 testSetRollover(t, false) 1028 } 1029 1030 func TestSetRolloverSerial(t *testing.T) { 1031 testSetRollover(t, true) 1032 } 1033 1034 func TestGetFirstAvailableFromCurrent(t *testing.T) { 1035 input := []struct { 1036 mask *sequence 1037 bytePos uint64 1038 bitPos uint64 1039 start uint64 1040 curr uint64 1041 end uint64 1042 }{ 1043 {&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos, 0, 0, 65536}, 1044 {&sequence{block: 0x0, count: 8}, 0, 0, 0, 0, 256}, 1045 {&sequence{block: 0x80000000, count: 8}, 1, 0, 0, 8, 256}, 1046 {&sequence{block: 0xC0000000, count: 8}, 0, 2, 0, 2, 256}, 1047 {&sequence{block: 0xE0000000, count: 8}, 0, 3, 0, 0, 256}, 1048 {&sequence{block: 0xFFFB1FFF, count: 8}, 2, 0, 14, 0, 256}, 1049 {&sequence{block: 0xFFFFFFFE, count: 8}, 3, 7, 0, 0, 256}, 1050 1051 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 14}}}, 4, 0, 0, 32, 512}, 1052 {&sequence{block: 0xfffeffff, count: 1, next: &sequence{block: 0xffffffff, count: 15}}, 1, 7, 0, 16, 512}, 1053 {&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 5, 7, 0, 16, 512}, 1054 {&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 9, 7, 0, 48, 512}, 1055 {&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xffffffef, count: 14}}, 19, 3, 0, 124, 512}, 1056 {&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0x0fffffff, count: 1}}, 60, 0, 0, 480, 512}, 1057 {&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 17, 7, 0, 124, 512}, 1058 {&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xffffffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 3, 5, 0, 124, 512}, 1059 {&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 13, 7, 0, 80, 512}, 1060 } 1061 1062 for n, i := range input { 1063 bytePos, bitPos, _ := getAvailableFromCurrent(i.mask, i.start, i.curr, i.end) 1064 if bytePos != i.bytePos || bitPos != i.bitPos { 1065 t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos) 1066 } 1067 } 1068 } 1069 1070 func TestMarshalJSON(t *testing.T) { 1071 expected := []byte("hello libnetwork") 1072 hnd := New(uint64(len(expected) * 8)) 1073 1074 for i, c := range expected { 1075 for j := 0; j < 8; j++ { 1076 if c&(1<<j) == 0 { 1077 continue 1078 } 1079 if err := hnd.Set(uint64(i*8 + j)); err != nil { 1080 t.Fatal(err) 1081 } 1082 } 1083 } 1084 1085 hstr := hnd.String() 1086 t.Log(hstr) 1087 marshaled, err := hnd.MarshalJSON() 1088 if err != nil { 1089 t.Fatalf("MarshalJSON() err = %v", err) 1090 } 1091 t.Logf("%s", marshaled) 1092 1093 // Serializations of hnd as would be marshaled by versions of the code 1094 // found in the wild. We need to support unmarshaling old versions to 1095 // maintain backwards compatibility with sequences persisted on disk. 1096 const ( 1097 goldenV0 = `"AAAAAAAAAIAAAAAAAAAAPRamNjYAAAAAAAAAAfYENpYAAAAAAAAAAUZ2pi4AAAAAAAAAAe72TtYAAAAAAAAAAQ=="` 1098 ) 1099 1100 if string(marshaled) != goldenV0 { 1101 t.Errorf("MarshalJSON() output differs from golden. Please add a new golden case to this test.") 1102 } 1103 1104 for _, tt := range []struct { 1105 name string 1106 data []byte 1107 }{ 1108 {name: "Live", data: marshaled}, 1109 {name: "Golden-v0", data: []byte(goldenV0)}, 1110 } { 1111 tt := tt 1112 t.Run("UnmarshalJSON="+tt.name, func(t *testing.T) { 1113 hnd2 := New(0) 1114 if err := hnd2.UnmarshalJSON(tt.data); err != nil { 1115 t.Errorf("UnmarshalJSON() err = %v", err) 1116 } 1117 1118 h2str := hnd2.String() 1119 t.Log(h2str) 1120 if hstr != h2str { 1121 t.Errorf("Unmarshaled a different bitmap: want %q, got %q", hstr, h2str) 1122 } 1123 }) 1124 } 1125 }