github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/queue/prefix_queue_test.go (about) 1 package queue 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 "time" 8 ) 9 10 func TestPrefixQueueClose(t *testing.T) { 11 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 12 pq, err := OpenPrefixQueue(file) 13 if err != nil { 14 t.Error(err) 15 } 16 defer pq.Drop() 17 18 if _, err = pq.EnqueueString("prefix", "value"); err != nil { 19 t.Error(err) 20 } 21 22 if pq.Length() != 1 { 23 t.Errorf("Expected queue length of 1, got %d", pq.Length()) 24 } 25 26 pq.Close() 27 28 if _, err = pq.DequeueString("prefix"); err != ErrDBClosed { 29 t.Errorf("Expected to get database closed error, got %s", err.Error()) 30 } 31 32 if pq.Length() != 0 { 33 t.Errorf("Expected queue length of 0, got %d", pq.Length()) 34 } 35 } 36 37 func TestPrefixQueueDrop(t *testing.T) { 38 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 39 pq, err := OpenPrefixQueue(file) 40 if err != nil { 41 t.Error(err) 42 } 43 44 if _, err = os.Stat(file); os.IsNotExist(err) { 45 t.Error(err) 46 } 47 48 pq.Drop() 49 50 if _, err = os.Stat(file); err == nil { 51 t.Error("Expected directory for test database to have been deleted") 52 } 53 } 54 55 func TestPrefixQueueIncompatibleType(t *testing.T) { 56 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 57 prq, err := OpenPriorityQueue(file, ASC) 58 if err != nil { 59 t.Error(err) 60 } 61 defer prq.Drop() 62 prq.Close() 63 64 if _, err = OpenPrefixQueue(file); err != ErrIncompatibleType { 65 t.Error("Expected priority queue to return ErrIncompatibleTypes when opening queuePriorityQueue") 66 } 67 } 68 69 func TestPrefixQueueEnqueue(t *testing.T) { 70 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 71 pq, err := OpenPrefixQueue(file) 72 if err != nil { 73 t.Error(err) 74 } 75 defer pq.Drop() 76 77 for i := 1; i <= 10; i++ { 78 if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil { 79 t.Error(err) 80 } 81 } 82 83 if pq.Length() != 10 { 84 t.Errorf("Expected queue size of 10, got %d", pq.Length()) 85 } 86 } 87 88 func TestPrefixQueueDequeue(t *testing.T) { 89 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 90 pq, err := OpenPrefixQueue(file) 91 if err != nil { 92 t.Error(err) 93 } 94 defer pq.Drop() 95 96 for i := 1; i <= 10; i++ { 97 if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil { 98 t.Error(err) 99 } 100 } 101 102 if pq.Length() != 10 { 103 t.Errorf("Expected queue length of 10, got %d", pq.Length()) 104 } 105 106 deqItem, err := pq.DequeueString("prefix") 107 if err != nil { 108 t.Error(err) 109 } 110 111 if pq.Length() != 9 { 112 t.Errorf("Expected queue length of 9, got %d", pq.Length()) 113 } 114 115 compStr := "value for item 1" 116 117 if deqItem.ToString() != compStr { 118 t.Errorf("Expected string to be '%s', got '%s'", compStr, deqItem.ToString()) 119 } 120 } 121 122 func TestPrefixQueueEncodeDecodePointerJSON(t *testing.T) { 123 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 124 pq, err := OpenPrefixQueue(file) 125 if err != nil { 126 t.Error(err) 127 } 128 defer pq.Drop() 129 130 type subObject struct { 131 Value *int 132 } 133 134 type object struct { 135 Value int 136 SubObject subObject 137 } 138 139 val := 0 140 obj := object{ 141 Value: 0, 142 SubObject: subObject{ 143 Value: &val, 144 }, 145 } 146 147 if _, err = pq.EnqueueObjectAsJSON([]byte("prefix"), obj); err != nil { 148 t.Error(err) 149 } 150 151 item, err := pq.Dequeue([]byte("prefix")) 152 if err != nil { 153 t.Error(err) 154 } 155 156 var itemObj object 157 if err := item.ToObjectFromJSON(&itemObj); err != nil { 158 t.Error(err) 159 } 160 161 if *itemObj.SubObject.Value != 0 { 162 t.Errorf("Expected object subobject value to be '0', got '%v'", *itemObj.SubObject.Value) 163 } 164 } 165 166 func TestPrefixQueuePeek(t *testing.T) { 167 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 168 pq, err := OpenPrefixQueue(file) 169 if err != nil { 170 t.Error(err) 171 } 172 defer pq.Drop() 173 174 compStr := "value for item" 175 176 if _, err = pq.EnqueueString("prefix", compStr); err != nil { 177 t.Error(err) 178 } 179 180 peekItem, err := pq.PeekString("prefix") 181 if err != nil { 182 t.Error(err) 183 } 184 185 if peekItem.ToString() != compStr { 186 t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString()) 187 } 188 189 if pq.Length() != 1 { 190 t.Errorf("Expected queue length of 1, got %d", pq.Length()) 191 } 192 } 193 194 func TestPrefixQueuePeekByID(t *testing.T) { 195 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 196 pq, err := OpenPrefixQueue(file) 197 if err != nil { 198 t.Error(err) 199 } 200 defer pq.Drop() 201 202 for i := 1; i <= 10; i++ { 203 if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil { 204 t.Error(err) 205 } 206 } 207 208 compStr := "value for item 3" 209 210 peekItem, err := pq.PeekByIDString("prefix", 3) 211 if err != nil { 212 t.Error(err) 213 } 214 215 if peekItem.ToString() != compStr { 216 t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString()) 217 } 218 219 if pq.Length() != 10 { 220 t.Errorf("Expected queue length of 10, got %d", pq.Length()) 221 } 222 } 223 224 func TestPrefixQueueUpdate(t *testing.T) { 225 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 226 pq, err := OpenPrefixQueue(file) 227 if err != nil { 228 t.Error(err) 229 } 230 defer pq.Drop() 231 232 for i := 1; i <= 10; i++ { 233 if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil { 234 t.Error(err) 235 } 236 } 237 238 item, err := pq.PeekByIDString("prefix", 3) 239 if err != nil { 240 t.Error(err) 241 } 242 243 oldCompStr := "value for item 3" 244 newCompStr := "new value for item 3" 245 246 if item.ToString() != oldCompStr { 247 t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString()) 248 } 249 250 updatedItem, err := pq.UpdateString("prefix", item.ID, newCompStr) 251 if err != nil { 252 t.Error(err) 253 } 254 255 if updatedItem.ToString() != newCompStr { 256 t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString()) 257 } 258 259 newItem, err := pq.PeekByIDString("prefix", 3) 260 if err != nil { 261 t.Error(err) 262 } 263 264 if newItem.ToString() != newCompStr { 265 t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString()) 266 } 267 } 268 269 func TestPrefixQueueUpdateString(t *testing.T) { 270 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 271 pq, err := OpenPrefixQueue(file) 272 if err != nil { 273 t.Error(err) 274 } 275 defer pq.Drop() 276 277 for i := 1; i <= 10; i++ { 278 if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil { 279 t.Error(err) 280 } 281 } 282 283 item, err := pq.PeekByIDString("prefix", 3) 284 if err != nil { 285 t.Error(err) 286 } 287 288 oldCompStr := "value for item 3" 289 newCompStr := "new value for item 3" 290 291 if item.ToString() != oldCompStr { 292 t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString()) 293 } 294 295 updatedItem, err := pq.UpdateString("prefix", item.ID, newCompStr) 296 if err != nil { 297 t.Error(err) 298 } 299 300 if updatedItem.ToString() != newCompStr { 301 t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString()) 302 } 303 304 newItem, err := pq.PeekByIDString("prefix", 3) 305 if err != nil { 306 t.Error(err) 307 } 308 309 if newItem.ToString() != newCompStr { 310 t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString()) 311 } 312 } 313 314 func TestPrefixQueueUpdateObject(t *testing.T) { 315 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 316 pq, err := OpenPrefixQueue(file) 317 if err != nil { 318 t.Error(err) 319 } 320 defer pq.Drop() 321 322 type object struct { 323 Value int 324 } 325 326 for i := 1; i <= 10; i++ { 327 if _, err = pq.EnqueueObject([]byte("prefix"), object{i}); err != nil { 328 t.Error(err) 329 } 330 } 331 332 item, err := pq.PeekByIDString("prefix", 3) 333 if err != nil { 334 t.Error(err) 335 } 336 337 oldCompObj := object{3} 338 newCompObj := object{33} 339 340 var obj object 341 if err := item.ToObject(&obj); err != nil { 342 t.Error(err) 343 } 344 345 if obj != oldCompObj { 346 t.Errorf("Expected object to be '%+v', got '%+v'", oldCompObj, obj) 347 } 348 349 updatedItem, err := pq.UpdateObject([]byte("prefix"), item.ID, newCompObj) 350 if err != nil { 351 t.Error(err) 352 } 353 354 if err := updatedItem.ToObject(&obj); err != nil { 355 t.Error(err) 356 } 357 358 if obj != newCompObj { 359 t.Errorf("Expected current object to be '%+v', got '%+v'", newCompObj, obj) 360 } 361 362 newItem, err := pq.PeekByIDString("prefix", 3) 363 if err != nil { 364 t.Error(err) 365 } 366 367 if err := newItem.ToObject(&obj); err != nil { 368 t.Error(err) 369 } 370 371 if obj != newCompObj { 372 t.Errorf("Expected new object to be '%+v', got '%+v'", newCompObj, obj) 373 } 374 } 375 376 func TestPrefixQueueUpdateObjectAsJSON(t *testing.T) { 377 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 378 pq, err := OpenPrefixQueue(file) 379 if err != nil { 380 t.Error(err) 381 } 382 defer pq.Drop() 383 384 type subObject struct { 385 Value *int 386 } 387 388 type object struct { 389 Value int 390 SubObject subObject 391 } 392 393 for i := 1; i <= 10; i++ { 394 obj := object{ 395 Value: i, 396 SubObject: subObject{ 397 Value: &i, 398 }, 399 } 400 401 if _, err = pq.EnqueueObjectAsJSON([]byte("prefix"), obj); err != nil { 402 t.Error(err) 403 } 404 } 405 406 item, err := pq.PeekByIDString("prefix", 3) 407 if err != nil { 408 t.Error(err) 409 } 410 411 oldCompObjVal := 3 412 oldCompObj := object{ 413 Value: 3, 414 SubObject: subObject{ 415 Value: &oldCompObjVal, 416 }, 417 } 418 newCompObjVal := 33 419 newCompObj := object{ 420 Value: 33, 421 SubObject: subObject{ 422 Value: &newCompObjVal, 423 }, 424 } 425 426 var obj object 427 if err := item.ToObjectFromJSON(&obj); err != nil { 428 t.Error(err) 429 } 430 431 if *obj.SubObject.Value != *oldCompObj.SubObject.Value { 432 t.Errorf("Expected object subobject value to be '%+v', got '%+v'", *oldCompObj.SubObject.Value, *obj.SubObject.Value) 433 } 434 435 updatedItem, err := pq.UpdateObjectAsJSON([]byte("prefix"), item.ID, newCompObj) 436 if err != nil { 437 t.Error(err) 438 } 439 440 if err := updatedItem.ToObjectFromJSON(&obj); err != nil { 441 t.Error(err) 442 } 443 444 if *obj.SubObject.Value != *newCompObj.SubObject.Value { 445 t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value) 446 } 447 448 newItem, err := pq.PeekByIDString("prefix", 3) 449 if err != nil { 450 t.Error(err) 451 } 452 453 if err := newItem.ToObjectFromJSON(&obj); err != nil { 454 t.Error(err) 455 } 456 457 if *obj.SubObject.Value != *newCompObj.SubObject.Value { 458 t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value) 459 } 460 } 461 462 func TestPrefixQueueUpdateOutOfBounds(t *testing.T) { 463 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 464 pq, err := OpenPrefixQueue(file) 465 if err != nil { 466 t.Error(err) 467 } 468 defer pq.Drop() 469 470 for i := 1; i <= 10; i++ { 471 if _, err = pq.EnqueueString("prefix", fmt.Sprintf("value for item %d", i)); err != nil { 472 t.Error(err) 473 } 474 } 475 476 if pq.Length() != 10 { 477 t.Errorf("Expected queue length of 10, got %d", pq.Length()) 478 } 479 480 deqItem, err := pq.DequeueString("prefix") 481 if err != nil { 482 t.Error(err) 483 } 484 485 if pq.Length() != 9 { 486 t.Errorf("Expected queue length of 9, got %d", pq.Length()) 487 } 488 489 if _, err = pq.Update([]byte("prefix"), deqItem.ID, []byte(`new value`)); err != ErrOutOfBounds { 490 t.Errorf("Expected to get queue out of bounds error, got %s", err.Error()) 491 } 492 493 if _, err = pq.Update([]byte("prefix"), deqItem.ID+1, []byte(`new value`)); err != nil { 494 t.Error(err) 495 } 496 } 497 498 func TestPrefixQueueEmpty(t *testing.T) { 499 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 500 pq, err := OpenPrefixQueue(file) 501 if err != nil { 502 t.Error(err) 503 } 504 defer pq.Drop() 505 506 _, err = pq.EnqueueString("prefix", "value for item") 507 if err != nil { 508 t.Error(err) 509 } 510 511 _, err = pq.DequeueString("prefix") 512 if err != nil { 513 t.Error(err) 514 } 515 516 _, err = pq.DequeueString("prefix") 517 if err != ErrEmpty { 518 t.Errorf("Expected to get empty error, got %s", err.Error()) 519 } 520 } 521 522 func TestPrefixQueueOutOfBounds(t *testing.T) { 523 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 524 pq, err := OpenPrefixQueue(file) 525 if err != nil { 526 t.Error(err) 527 } 528 defer pq.Drop() 529 530 _, err = pq.EnqueueString("prefix", "value for item") 531 if err != nil { 532 t.Error(err) 533 } 534 535 _, err = pq.PeekByIDString("prefix", 2) 536 if err != ErrOutOfBounds { 537 t.Errorf("Expected to get queue out of bounds error, got %s", err.Error()) 538 } 539 } 540 541 func BenchmarkPrefixQueueEnqueue(b *testing.B) { 542 // Open test database 543 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 544 pq, err := OpenPrefixQueue(file) 545 if err != nil { 546 b.Error(err) 547 } 548 defer pq.Drop() 549 550 b.ResetTimer() 551 b.ReportAllocs() 552 553 for n := 0; n < b.N; n++ { 554 _, _ = pq.Enqueue([]byte("prefix"), []byte("value")) 555 } 556 } 557 558 func BenchmarkPrefixQueueDequeue(b *testing.B) { 559 // Open test database 560 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 561 pq, err := OpenPrefixQueue(file) 562 if err != nil { 563 b.Error(err) 564 } 565 defer pq.Drop() 566 567 // Fill with dummy data 568 for n := 0; n < b.N; n++ { 569 if _, err = pq.Enqueue([]byte("prefix"), []byte("value")); err != nil { 570 b.Error(err) 571 } 572 } 573 574 // Start benchmark 575 b.ResetTimer() 576 b.ReportAllocs() 577 578 for n := 0; n < b.N; n++ { 579 _, _ = pq.Dequeue([]byte("prefix")) 580 } 581 }