github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/queue/queue_test.go (about) 1 package queue 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 "time" 8 ) 9 10 func TestQueueClose(t *testing.T) { 11 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 12 q, err := OpenQueue(file) 13 if err != nil { 14 t.Error(err) 15 } 16 defer q.Drop() 17 18 if _, err = q.EnqueueString("value"); err != nil { 19 t.Error(err) 20 } 21 22 if q.Length() != 1 { 23 t.Errorf("Expected queue length of 1, got %d", q.Length()) 24 } 25 26 q.Close() 27 28 if _, err = q.Dequeue(); err != ErrDBClosed { 29 t.Errorf("Expected to get database closed error, got %s", err.Error()) 30 } 31 32 if q.Length() != 0 { 33 t.Errorf("Expected queue length of 0, got %d", q.Length()) 34 } 35 } 36 37 func TestQueueDrop(t *testing.T) { 38 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 39 q, err := OpenQueue(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 q.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 TestQueueIncompatibleType(t *testing.T) { 56 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 57 pq, err := OpenPriorityQueue(file, ASC) 58 if err != nil { 59 t.Error(err) 60 } 61 defer pq.Drop() 62 pq.Close() 63 64 if _, err = OpenQueue(file); err != ErrIncompatibleType { 65 t.Error("Expected priority queue to return ErrIncompatibleTypes when opening queuePriorityQueue") 66 } 67 } 68 69 func TestQueueEnqueue(t *testing.T) { 70 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 71 q, err := OpenQueue(file) 72 if err != nil { 73 t.Error(err) 74 } 75 defer q.Drop() 76 77 for i := 1; i <= 10; i++ { 78 if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil { 79 t.Error(err) 80 } 81 } 82 83 if q.Length() != 10 { 84 t.Errorf("Expected queue size of 10, got %d", q.Length()) 85 } 86 } 87 88 func TestQueueDequeue(t *testing.T) { 89 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 90 q, err := OpenQueue(file) 91 if err != nil { 92 t.Error(err) 93 } 94 defer q.Drop() 95 96 for i := 1; i <= 10; i++ { 97 if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil { 98 t.Error(err) 99 } 100 } 101 102 if q.Length() != 10 { 103 t.Errorf("Expected queue length of 10, got %d", q.Length()) 104 } 105 106 deqItem, err := q.Dequeue() 107 if err != nil { 108 t.Error(err) 109 } 110 111 if q.Length() != 9 { 112 t.Errorf("Expected queue length of 9, got %d", q.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 TestQueueEncodeDecodePointerJSON(t *testing.T) { 123 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 124 q, err := OpenQueue(file) 125 if err != nil { 126 t.Error(err) 127 } 128 defer q.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 = q.EnqueueObjectAsJSON(obj); err != nil { 148 t.Error(err) 149 } 150 151 item, err := q.Dequeue() 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 TestQueuePeek(t *testing.T) { 167 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 168 q, err := OpenQueue(file) 169 if err != nil { 170 t.Error(err) 171 } 172 defer q.Drop() 173 174 compStr := "value for item" 175 176 if _, err = q.EnqueueString(compStr); err != nil { 177 t.Error(err) 178 } 179 180 peekItem, err := q.Peek() 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 q.Length() != 1 { 190 t.Errorf("Expected queue length of 1, got %d", q.Length()) 191 } 192 } 193 194 func TestQueuePeekByOffset(t *testing.T) { 195 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 196 q, err := OpenQueue(file) 197 if err != nil { 198 t.Error(err) 199 } 200 defer q.Drop() 201 202 for i := 1; i <= 10; i++ { 203 if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil { 204 t.Error(err) 205 } 206 } 207 208 compStrFirst := "value for item 1" 209 compStrLast := "value for item 10" 210 compStr := "value for item 4" 211 212 peekFirstItem, err := q.PeekByOffset(0) 213 if err != nil { 214 t.Error(err) 215 } 216 217 if peekFirstItem.ToString() != compStrFirst { 218 t.Errorf("Expected string to be '%s', got '%s'", compStrFirst, peekFirstItem.ToString()) 219 } 220 221 peekLastItem, err := q.PeekByOffset(9) 222 if err != nil { 223 t.Error(err) 224 } 225 226 if peekLastItem.ToString() != compStrLast { 227 t.Errorf("Expected string to be '%s', got '%s'", compStrLast, peekLastItem.ToString()) 228 } 229 230 peekItem, err := q.PeekByOffset(3) 231 if err != nil { 232 t.Error(err) 233 } 234 235 if peekItem.ToString() != compStr { 236 t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString()) 237 } 238 239 if q.Length() != 10 { 240 t.Errorf("Expected queue length of 10, got %d", q.Length()) 241 } 242 } 243 244 func TestQueuePeekByID(t *testing.T) { 245 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 246 q, err := OpenQueue(file) 247 if err != nil { 248 t.Error(err) 249 } 250 defer q.Drop() 251 252 for i := 1; i <= 10; i++ { 253 if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil { 254 t.Error(err) 255 } 256 } 257 258 compStr := "value for item 3" 259 260 peekItem, err := q.PeekByID(3) 261 if err != nil { 262 t.Error(err) 263 } 264 265 if peekItem.ToString() != compStr { 266 t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString()) 267 } 268 269 if q.Length() != 10 { 270 t.Errorf("Expected queue length of 10, got %d", q.Length()) 271 } 272 } 273 274 func TestQueueUpdate(t *testing.T) { 275 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 276 q, err := OpenQueue(file) 277 if err != nil { 278 t.Error(err) 279 } 280 defer q.Drop() 281 282 for i := 1; i <= 10; i++ { 283 if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil { 284 t.Error(err) 285 } 286 } 287 288 item, err := q.PeekByID(3) 289 if err != nil { 290 t.Error(err) 291 } 292 293 oldCompStr := "value for item 3" 294 newCompStr := "new value for item 3" 295 296 if item.ToString() != oldCompStr { 297 t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString()) 298 } 299 300 updatedItem, err := q.Update(item.ID, []byte(newCompStr)) 301 if err != nil { 302 t.Error(err) 303 } 304 305 if updatedItem.ToString() != newCompStr { 306 t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString()) 307 } 308 309 newItem, err := q.PeekByID(3) 310 if err != nil { 311 t.Error(err) 312 } 313 314 if newItem.ToString() != newCompStr { 315 t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString()) 316 } 317 } 318 319 func TestQueueUpdateString(t *testing.T) { 320 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 321 q, err := OpenQueue(file) 322 if err != nil { 323 t.Error(err) 324 } 325 defer q.Drop() 326 327 for i := 1; i <= 10; i++ { 328 if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil { 329 t.Error(err) 330 } 331 } 332 333 item, err := q.PeekByID(3) 334 if err != nil { 335 t.Error(err) 336 } 337 338 oldCompStr := "value for item 3" 339 newCompStr := "new value for item 3" 340 341 if item.ToString() != oldCompStr { 342 t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString()) 343 } 344 345 updatedItem, err := q.UpdateString(item.ID, newCompStr) 346 if err != nil { 347 t.Error(err) 348 } 349 350 if updatedItem.ToString() != newCompStr { 351 t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString()) 352 } 353 354 newItem, err := q.PeekByID(3) 355 if err != nil { 356 t.Error(err) 357 } 358 359 if newItem.ToString() != newCompStr { 360 t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString()) 361 } 362 } 363 364 func TestQueueUpdateObject(t *testing.T) { 365 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 366 q, err := OpenQueue(file) 367 if err != nil { 368 t.Error(err) 369 } 370 defer q.Drop() 371 372 type object struct { 373 Value int 374 } 375 376 for i := 1; i <= 10; i++ { 377 if _, err = q.EnqueueObject(object{i}); err != nil { 378 t.Error(err) 379 } 380 } 381 382 item, err := q.PeekByID(3) 383 if err != nil { 384 t.Error(err) 385 } 386 387 oldCompObj := object{3} 388 newCompObj := object{33} 389 390 var obj object 391 if err := item.ToObject(&obj); err != nil { 392 t.Error(err) 393 } 394 395 if obj != oldCompObj { 396 t.Errorf("Expected object to be '%+v', got '%+v'", oldCompObj, obj) 397 } 398 399 updatedItem, err := q.UpdateObject(item.ID, newCompObj) 400 if err != nil { 401 t.Error(err) 402 } 403 404 if err := updatedItem.ToObject(&obj); err != nil { 405 t.Error(err) 406 } 407 408 if obj != newCompObj { 409 t.Errorf("Expected current object to be '%+v', got '%+v'", newCompObj, obj) 410 } 411 412 newItem, err := q.PeekByID(3) 413 if err != nil { 414 t.Error(err) 415 } 416 417 if err := newItem.ToObject(&obj); err != nil { 418 t.Error(err) 419 } 420 421 if obj != newCompObj { 422 t.Errorf("Expected new object to be '%+v', got '%+v'", newCompObj, obj) 423 } 424 } 425 426 func TestQueueUpdateObjectAsJSON(t *testing.T) { 427 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 428 q, err := OpenQueue(file) 429 if err != nil { 430 t.Error(err) 431 } 432 defer q.Drop() 433 434 type subObject struct { 435 Value *int 436 } 437 438 type object struct { 439 Value int 440 SubObject subObject 441 } 442 443 for i := 1; i <= 10; i++ { 444 obj := object{ 445 Value: i, 446 SubObject: subObject{ 447 Value: &i, 448 }, 449 } 450 451 if _, err = q.EnqueueObjectAsJSON(obj); err != nil { 452 t.Error(err) 453 } 454 } 455 456 item, err := q.PeekByID(3) 457 if err != nil { 458 t.Error(err) 459 } 460 461 oldCompObjVal := 3 462 oldCompObj := object{ 463 Value: 3, 464 SubObject: subObject{ 465 Value: &oldCompObjVal, 466 }, 467 } 468 newCompObjVal := 33 469 newCompObj := object{ 470 Value: 33, 471 SubObject: subObject{ 472 Value: &newCompObjVal, 473 }, 474 } 475 476 var obj object 477 if err := item.ToObjectFromJSON(&obj); err != nil { 478 t.Error(err) 479 } 480 481 if *obj.SubObject.Value != *oldCompObj.SubObject.Value { 482 t.Errorf("Expected object subobject value to be '%+v', got '%+v'", *oldCompObj.SubObject.Value, *obj.SubObject.Value) 483 } 484 485 updatedItem, err := q.UpdateObjectAsJSON(item.ID, newCompObj) 486 if err != nil { 487 t.Error(err) 488 } 489 490 if err := updatedItem.ToObjectFromJSON(&obj); err != nil { 491 t.Error(err) 492 } 493 494 if *obj.SubObject.Value != *newCompObj.SubObject.Value { 495 t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value) 496 } 497 498 newItem, err := q.PeekByID(3) 499 if err != nil { 500 t.Error(err) 501 } 502 503 if err := newItem.ToObjectFromJSON(&obj); err != nil { 504 t.Error(err) 505 } 506 507 if *obj.SubObject.Value != *newCompObj.SubObject.Value { 508 t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value) 509 } 510 } 511 512 func TestQueueUpdateOutOfBounds(t *testing.T) { 513 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 514 q, err := OpenQueue(file) 515 if err != nil { 516 t.Error(err) 517 } 518 defer q.Drop() 519 520 for i := 1; i <= 10; i++ { 521 if _, err = q.EnqueueString(fmt.Sprintf("value for item %d", i)); err != nil { 522 t.Error(err) 523 } 524 } 525 526 if q.Length() != 10 { 527 t.Errorf("Expected queue length of 10, got %d", q.Length()) 528 } 529 530 deqItem, err := q.Dequeue() 531 if err != nil { 532 t.Error(err) 533 } 534 535 if q.Length() != 9 { 536 t.Errorf("Expected queue length of 9, got %d", q.Length()) 537 } 538 539 if _, err = q.Update(deqItem.ID, []byte(`new value`)); err != ErrOutOfBounds { 540 t.Errorf("Expected to get queue out of bounds error, got %s", err.Error()) 541 } 542 543 if _, err = q.Update(deqItem.ID+1, []byte(`new value`)); err != nil { 544 t.Error(err) 545 } 546 } 547 548 func TestQueueEmpty(t *testing.T) { 549 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 550 q, err := OpenQueue(file) 551 if err != nil { 552 t.Error(err) 553 } 554 defer q.Drop() 555 556 _, err = q.EnqueueString("value for item") 557 if err != nil { 558 t.Error(err) 559 } 560 561 _, err = q.Dequeue() 562 if err != nil { 563 t.Error(err) 564 } 565 566 _, err = q.Dequeue() 567 if err != ErrEmpty { 568 t.Errorf("Expected to get empty error, got %s", err.Error()) 569 } 570 } 571 572 func TestQueueOutOfBounds(t *testing.T) { 573 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 574 q, err := OpenQueue(file) 575 if err != nil { 576 t.Error(err) 577 } 578 defer q.Drop() 579 580 _, err = q.EnqueueString("value for item") 581 if err != nil { 582 t.Error(err) 583 } 584 585 _, err = q.PeekByOffset(2) 586 if err != ErrOutOfBounds { 587 t.Errorf("Expected to get queue out of bounds error, got %s", err.Error()) 588 } 589 } 590 591 func BenchmarkQueueEnqueue(b *testing.B) { 592 // Open test database 593 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 594 q, err := OpenQueue(file) 595 if err != nil { 596 b.Error(err) 597 } 598 defer q.Drop() 599 600 b.ResetTimer() 601 b.ReportAllocs() 602 603 for n := 0; n < b.N; n++ { 604 _, _ = q.Enqueue([]byte("value")) 605 } 606 } 607 608 func BenchmarkQueueDequeue(b *testing.B) { 609 // Open test database 610 file := fmt.Sprintf("test_db_%d", time.Now().UnixNano()) 611 q, err := OpenQueue(file) 612 if err != nil { 613 b.Error(err) 614 } 615 defer q.Drop() 616 617 // Fill with dummy data 618 for n := 0; n < b.N; n++ { 619 if _, err = q.Enqueue([]byte("value")); err != nil { 620 b.Error(err) 621 } 622 } 623 624 // Start benchmark 625 b.ResetTimer() 626 b.ReportAllocs() 627 628 for n := 0; n < b.N; n++ { 629 _, _ = q.Dequeue() 630 } 631 }